2007-05-03
| Table of Contents: |
| Rate This Article: | Add This Article To: |
( Page 2 of 2 )
Employing a Callback or (Delegate)
What happens when you need to use the file names in your main program code? The solution that's been presented doesn't work all that well. I almost always need to separate the directory search code from the code that handles the search results. It might be adequate to do everything from within the thread if the code is simply populating a StringCollection object. But good software architecture might dictate that your directory search code and your directory handling be separate. When this is the case (and it usually is), you should create a delegate method that the thread calls when it finds a new directory. You may ask, "why a delegate method, why not just call a handler method?" The answer is simple. While these examples are within a single class, your directory search and directory handling code will probably be in separate classes. When this is true, a delegate method is the best choice.
There are several good articles covering delegates on DevSource.com. To reference these, read the articles at http://www.devsource.com/article2/0,1895,2104407,00.asp and http://www.devsource.com/article2/0,1895,1544618,00.asp.
The first thing we'll need to do is create a delegate method that will receive the directory information. The method we'll use will simple display the directory to the console. Most code, though, will do more with the directory than simply display its name. The following method shows the method that will display the directory name:
static public void ShowDir(string strDir)
{
Console.WriteLine(strDir);
}
The next thing we must do is prototype a delegate and then declare a variable of the delegate type. The following code does this:
public delegate void ShowDirMethod(string strDir); public ShowDirMethod m_DirectoryHandlingMethod;
Before the thread is kicked off, the delegate to the ShowDir method must be created as follows:
m_DirectoryHandlingMethod = new ShowDirMethod(ShowDir);
Finally, the thread code can call the delegate method which will process the directory. The code to do this is as follows:
m_DirectoryHandlingMethod(strIndent + strDirName);
The entire program with the delegate directory handling can be seen below:
// Thread variable.
static private Thread m_Thread;
// This method is kicked off by the Thread.Start method.
static public void StartSearch()
{
// Call our ExamineDir method.
ExamineDir(@"C:\", 0);
}
// New delegate method that recieves the directory name.
static public void ShowDir(string strDir)
{
Console.WriteLine(strDir);
}
// Delegate method prototype.
public delegate void ShowDirMethod(string strDir);
// Delegate method object declaration.
static public ShowDirMethod m_DirectoryHandlingMethod;
// This is the ExamineDir method we've been using.
static public void ExamineDir(string strDir,int nIndex)
{
try
{
foreach (string strDirName in Directory.GetDirectories(strDir))
{
string strIndent = new String( ' ', nIndex );
// Call the delegate that will handle the directory name.
m_DirectoryHandlingMethod(strIndent + strDirName);
ExamineDir(strDirName, nIndex+2);
}
}
catch{}
}
static void Main(string[] args)
{
// Create a thread object.
m_Thread = new Thread( new ThreadStart(StartSearch));
// Create the delegate.
m_DirectoryHandlingMethod = new ShowDirMethod(ShowDir);
// Start the thread. This kicks off the StartSearch method.
m_Thread.Start();
// Wait until the thread is done.
while (m_Thread.ThreadState == ThreadState.Running)
{
Thread.Sleep(10);
}
Console.WriteLine("\n\n***Done");
}
There are two sample programs that demonstrate what we've talked about to this point. The first is named RecursiveDirectoryDemo and can be downloaded
Authentication
There is one last thing I want to cover. You might want to perform a directory search over the network. That's fine if you are already logged on to the remote machine, or the credentials for the remote machine won't get in your way. But if you haven't logged on, you can authenticate programmatically and perform the directory search.
There is a class named Impersonator that you'll need to use. It can be found in a Microsoft knowledge base article at http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158. You must use this class before you start the directory search.
Let's say you want to use the UNC path \\Machine1\Share1. You would need to set the starting directory as @"\\Machine1\Share1" when you call the ExamineDir method the first time as follows:
ExamineDir(@"\\Machine1\Share1");
or if you want to use the "indented" version:
ExamineDir(@"\\Machine1\Share1", 0);
Before you call the ExaminDir method, though, you must employ the Impersonator class as follows:
using(new Impersonator("UserName", "DomainName", "Password"))
{
ExamineDir(@"\\Machine1\Share1");
}
Conclusion
Searching directories recursively is a useful task. I have used this technique dozens of times in my software development for various purposes. And while it may seem daunting at first, once you dig in and dissect the code it's very manageable.
![]() |
|


