Search files in a directory hierarchy for a target string in C#

I've been using Windows 7 for a couple of weeks and one of the things I find most annoying (in Vista, too) is that it doesn't search files properly.  Despite setting this indexing setting and adding that file extension to whatever list, it just won't search inside the files I want it to such as C# program files with a .cs extension. (It has become a long-standing joke that Microsoft can't search files and probably never will.)

So in frustration I wrote my own file searcher.

The following code shows the program's key pieces.

// If we launched from the Send To menu,
// use the argument as our directory.
private void Form1_Load(object sender, EventArgs e)
{
if (System.Environment.GetCommandLineArgs().Length > 1)
{
txtDirectory.Text = System.Environment.GetCommandLineArgs()[1];
txtTarget.Focus();
}
}

// Search.
private void btnSearch_Click(object sender, EventArgs e)
{
lstResults.Items.Clear();
DirectoryInfo dir_info = new DirectoryInfo(txtDirectory.Text);

ListFiles(lstResults, cboPattern.Text, dir_info, txtTarget.Text);

System.Media.SystemSounds.Beep.Play();
}

// Add the files in this directory's subtree
// that match the pattern to the ListBox.
private void ListFiles(ListBox lst, string pattern, DirectoryInfo dir_info, string target)
{
// Get the files in this directory.
FileInfo[] fs_infos = dir_info.GetFiles(pattern);
foreach (FileInfo fs_info in fs_infos)
{
if (target.Length == 0)
{
lstResults.Items.Add(fs_info.FullName);
}
else
{
string txt = File.ReadAllText(fs_info.FullName);
if (txt.IndexOf(target, StringComparison.OrdinalIgnoreCase) >= 0)
{
lstResults.Items.Add(fs_info.FullName);
}
}
}

// Search subdirectories.
DirectoryInfo[] subdirs = dir_info.GetDirectories();
foreach (DirectoryInfo subdir in subdirs)
{
ListFiles(lst, pattern, subdir, target);
}
}

When the program starts, it checks its command line arguments. The first one is always the name of the executing program. If there is a second argument, then it should be the name of a directory dragged onto the executable or sent to the program via the Send To menu so the program enters it in the Directory TextBox.

(To make using this program easy, I added it to my Send To menu. Then I can right-click a directory, open the Send To menu, and select this program to make it search the directory. For more information on adding items to the Send To menu, see Add items to the "Send To" menu.)

When you click the Search button, the program clears its results list, makes a DirectoryInfo object representing the start directory, and calls the ListFiles function.

ListFiles uses the DirectoryInfo object's GetFiles method to get a list of files that match the file pattern. If there is no target string to look for, the program simply adds the files to the result list.

If there is a target string, the program uses System.IO.File.ReadAllText to read the file's contents into a string. If the target is in the file, the program adds the file to the list.

After searching the files in this directory, the program uses the DirectoryInfo object's GetDirectories method to get a list of its subdirectories. The program calls ListFiles recursively to search each subdirectory.

The result isn't as fancy as Windows Explorer's search. You can't search by file date, size, author, rating, or any of the other zillion things you would never want to use in a search.

However, it works and can search any kind of file. It's even a lot faster than Windows' search. Now if Microsoft would just get a clue. Perhaps they can include a working search tool in the next version of Windows.

   

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this post.
Comments
  • No comments exist for this post.
Leave a comment

Submitted comments are subject to moderation before being displayed.

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.