Solved

Searching for file in all folders using C#

Posted on 2014-01-03
17
1,368 Views
Last Modified: 2014-01-07
Hi, I'm trying to search for files that are shortcuts in ALL directories including subfolders. I used this code but seems like it only searches one folder? I put C as the folder to search, but doesn't seem to go into every folder. Any help would be appreciated. Thanks in advance.

void DirSearch(string sDir)
        {
            try
            {
                foreach (string d in Directory.GetDirectories(sDir))
                {
                    foreach (string f in Directory.GetFiles(d, "*.lnk"))
                    {
                        lstFilesFound.Items.Add(f);
                    }
                    DirSearch(d);
                }
            }
            catch (System.Exception excpt)
            {
                Console.WriteLine(excpt.Message);
            }
        }

Open in new window

        private void button3_Click(object sender, RoutedEventArgs e)
        {
            DirSearch(@"C:\\");
        }

Open in new window

0
Comment
Question by:TeknikDev
17 Comments
 
LVL 22

Expert Comment

by:Ivo Stoykov
Comment Utility
This is shorter
string[] files = Directory.GetFiles(@"c:\files\folder1\", "*.*",SearchOption.AllDirectories);

Open in new window


Your source should be:
void DirSearch(string dir)
{
    try
    {
        foreach (string f in Directory.GetFiles(dir)) {  lstFilesFound.Items.Add(f);  }
        foreach (string d in Directory.GetDirectories(dir))
        {
//            lstFilesFound.Items.Add(d); // this will add directory name in the list
            DirSearch(d);
        }
    }
    catch (System.Exception e)
    {
        Console.WriteLine(e.Message);
    }
}

Open in new window

private void button3_Click(object sender, RoutedEventArgs e)
{
   DirSearch(@"C:\");
}

Open in new window

0
 
LVL 5

Expert Comment

by:Eduardo Goicovich
Comment Utility
Better use

string[] files=Directory.GetFiles("C:\\",   "*.lnk",   SearchOption.AllDirectories)
0
 

Author Comment

by:TeknikDev
Comment Utility
I don't see how you are using the shorter version of
string[] files 

Open in new window

0
 

Author Comment

by:TeknikDev
Comment Utility
I get "Access denied to Documents and Settings folder". Is there a way to bypass folders that I do not have access to? Also, how can I create a searching splash....? It takes a while to search and user may not know its doing anything.

                foreach (string f in Directory.GetFiles(dir, "*.lnk",  SearchOption.AllDirectories)) ;
                foreach (string d in Directory.GetDirectories(dir))
                {

Open in new window

0
 
LVL 62

Expert Comment

by:Fernando Soto
Comment Utility
Hi TeknikDev;

As stated in the C# Programming Guide the weakness in using GetDirectories and GetFiles is, "The weakness in this approach is that if any one of the subdirectories under the specified root causes a DirectoryNotFoundException or UnauthorizedAccessException, the whole method fails and returns no directories. The same is true when you use the GetFiles method. If you have to handle these exceptions on specific subfolders, you must manually walk the directory tree, as shown in the following examples.", they give two examples the first using recursion and the second walking the directory tree manually. Seeming you are looking to visit all directories do not use the recursion option as you will get a stack overflow. In walking the tree manually when trying to go into a directory you will need to catch the exception and try to elevate your permissions or just skip those directories. See the Microsoft documentation.

How to: Iterate Through a Directory Tree (C# Programming Guide)
0
 

Author Comment

by:TeknikDev
Comment Utility
Hey Fernando, can you provide the actual code on how to do this? Thanks
0
 
LVL 62

Expert Comment

by:Fernando Soto
Comment Utility
Hi TeknikDev;

The code is at the bottom of the link I posted above re-posted below. This code uses stack iteration as opposed to recursion.

public class StackBasedIteration
{
    static void Main(string[] args)
    {
        // Specify the starting folder on the command line, or in  
        // Visual Studio in the Project > Properties > Debug pane.
        TraverseTree(args[0]);

        Console.WriteLine("Press any key");
        Console.ReadKey();
    }

    public static void TraverseTree(string root)
    {
        // Data structure to hold names of subfolders to be 
        // examined for files.
        Stack<string> dirs = new Stack<string>(20);

        if (!System.IO.Directory.Exists(root))
        {
            throw new ArgumentException();
        }
        dirs.Push(root);

        while (dirs.Count > 0)
        {
            string currentDir = dirs.Pop();
            string[] subDirs;
            try
            {
                subDirs = System.IO.Directory.GetDirectories(currentDir);
            }
            // An UnauthorizedAccessException exception will be thrown if we do not have 
            // discovery permission on a folder or file. It may or may not be acceptable  
            // to ignore the exception and continue enumerating the remaining files and  
            // folders. It is also possible (but unlikely) that a DirectoryNotFound exception  
            // will be raised. This will happen if currentDir has been deleted by 
            // another application or thread after our call to Directory.Exists. The  
            // choice of which exceptions to catch depends entirely on the specific task  
            // you are intending to perform and also on how much you know with certainty  
            // about the systems on which this code will run. 
            catch (UnauthorizedAccessException e)
            {                    
                Console.WriteLine(e.Message);
                continue;
            }
            catch (System.IO.DirectoryNotFoundException e)
            {
                Console.WriteLine(e.Message);
                continue;
            }

            string[] files = null;
            try
            {
                files = System.IO.Directory.GetFiles(currentDir);
            }

            catch (UnauthorizedAccessException e)
            {

                Console.WriteLine(e.Message);
                continue;
            }

            catch (System.IO.DirectoryNotFoundException e)
            {
                Console.WriteLine(e.Message);
                continue;
            }
            // Perform the required action on each file here. 
            // Modify this block to perform your required task. 
            foreach (string file in files)
            {
                try
                {
                    // Perform whatever action is required in your scenario.
                    System.IO.FileInfo fi = new System.IO.FileInfo(file);
                    Console.WriteLine("{0}: {1}, {2}", fi.Name, fi.Length, fi.CreationTime);
                }
                catch (System.IO.FileNotFoundException e)
                {
                    // If file was deleted by a separate application 
                    //  or thread since the call to TraverseTree() 
                    // then just continue.
                    Console.WriteLine(e.Message);
                    continue;
                }
            }

            // Push the subdirectories onto the stack for traversal. 
            // This could also be done before handing the files. 
            foreach (string str in subDirs)
                dirs.Push(str);
        }
    }
}

Open in new window

0
 

Author Comment

by:TeknikDev
Comment Utility
Thanks for this...but how can I re-write it so that it matches my original code? I'm very new to C#. Sorry but thank you for the assistance.

How will this work on a WPF form and executed by a click of  abutton.


I copied it freshly into a new project and then changed the debug starting object and set the working directory in Debug to C:\ (under Start Options) and get the error:

Index was outside the bounds of the array for TraverseTree(args[0]);
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 62

Expert Comment

by:Fernando Soto
Comment Utility
Hi TeknikDev;

The below code was modify to work with your setup. The only thing that is not there is getting elevated permissions. So currently it will get all files with *.lnk except for those that have access denied. As far as displaying it in a WPF view it all depends on how you have designed it and communicate with the view.

I used a List<string> for  lstFilesFound in the below code.
 
private void button3_Click(object sender, EventArgs e)
{
    DirSearch(@"C:\\");
    // Assign your lstFilesFound to a ListBox to see results
    listBox1.DataSource = lstFilesFound;
}

void DirSearch(string sDir)
{           

    // Data structure to hold names of subfolders to be 
    // examined for files.
    Stack<string> dirs = new Stack<string>(20);

    if (!System.IO.Directory.Exists(sDir))
    {
        throw new ArgumentException();
    }
    dirs.Push(sDir);

    while (dirs.Count > 0)
    {
        string currentDir = dirs.Pop();
        string[] subDirs = null;
        try
        {
            subDirs = System.IO.Directory.GetDirectories(currentDir);
        }
        // An UnauthorizedAccessException exception will be thrown if we do not have 
        // discovery permission on a folder or file. It may or may not be acceptable  
        // to ignore the exception and continue enumerating the remaining files and  
        // folders. It is also possible (but unlikely) that a DirectoryNotFound exception  
        // will be raised. This will happen if currentDir has been deleted by 
        // another application or thread after our call to Directory.Exists. The  
        // choice of which exceptions to catch depends entirely on the specific task  
        // you are intending to perform and also on how much you know with certainty  
        // about the systems on which this code will run. 
        catch (UnauthorizedAccessException e)
        {

            Console.WriteLine(e.Message);
            continue;
        }
        catch (System.IO.PathTooLongException e)
        {
            Console.WriteLine(e.Message + " : " + currentDir);
            continue;
        }
        catch (System.IO.DirectoryNotFoundException e)
        {
            Console.WriteLine(e.Message);
            continue;
        }

        string[] files = null;
        try
        {
            files = System.IO.Directory.GetFiles(currentDir, "*.lnk");
        }
        catch (System.IO.PathTooLongException e)
        {
            Console.WriteLine(e.Message + " : " + currentDir);
            continue;
        }
        catch (UnauthorizedAccessException e)
        {
            Console.WriteLine(e.Message);
            continue;
        }
        catch (System.IO.DirectoryNotFoundException e)
        {
            Console.WriteLine(e.Message);
            continue;
        }
        // Perform the required action on each file here. 
        // Modify this block to perform your required task. 
        foreach (string file in files)
        {
            try
            {
                // Perform whatever action is required in your scenario.
                System.IO.FileInfo fi = new System.IO.FileInfo(file);
                lstFilesFound.Add(fi.FullName);
            }
            catch (System.IO.PathTooLongException e)
            {
                Console.WriteLine(e.Message + " : " + file);
                continue;
            }
            catch (System.IO.FileNotFoundException e)
            {
                // If file was deleted by a separate application 
                //  or thread since the call to TraverseTree() 
                // then just continue.
                Console.WriteLine(e.Message);
                continue;
            }
        }

        // Push the subdirectories onto the stack for traversal. 
        // This could also be done before handing the files. 
        foreach (string str in subDirs)
            dirs.Push(str);

    }
}

Open in new window

0
 

Author Comment

by:TeknikDev
Comment Utility
Ok ill give it a whirl, I'll replace the Console.Writeline with MessageBox.Show.
0
 

Author Comment

by:TeknikDev
Comment Utility
Ok  got this error message in the button click function:

listbox1.Datasource = lstFilesFound;

Error      1      'System.Windows.Controls.ListBox' does not contain a definition for 'DataSource' and no extension method 'DataSource' accepting a first argument of type 'System.Windows.Controls.ListBox' could be found (are you missing a using directive or an assembly reference?)      C:\visual studio 2010\Projects\WpfApplication2\WpfApplication2\MainWindow.xaml.cs      26      22      WpfApplication2


Error      2      The name 'lstFilesFound' does not exist in the current context      C:\visual studio 2010\Projects\WpfApplication2\WpfApplication2\MainWindow.xaml.cs      26      35      WpfApplication2
0
 
LVL 62

Accepted Solution

by:
Fernando Soto earned 500 total points
Comment Utility
My postings were in the Windows Form platform and not WPF. The following is a sample code in WPF.

namespace WpfApplication2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            // Used to bind the list of found files to the list box
            this.DataContext = FilesFound;
        }

        // Holds a collection of all the found files
        ObservableCollection<String> lstFilesFound = new ObservableCollection<string>();

        // Property used by the list box to display the list of files
        public ObservableCollection<string> FilesFound { get { return lstFilesFound; } }

        private void Button3_Click(object sender, RoutedEventArgs e)
        {
            DirSearch(@"C:\\");
            Console.WriteLine();
        }

        void DirSearch(string sDir)
        {
            // Data structure to hold names of subfolders to be 
            // examined for files.
            Stack<string> dirs = new Stack<string>(20);

            if (!System.IO.Directory.Exists(sDir))
            {
                throw new ArgumentException();
            }
            dirs.Push(sDir);

            while (dirs.Count > 0)
            {
                string currentDir = dirs.Pop();
                string[] subDirs = null;
                try
                {
                    subDirs = System.IO.Directory.GetDirectories(currentDir);
                }
                // An UnauthorizedAccessException exception will be thrown if we do not have 
                // discovery permission on a folder or file. It may or may not be acceptable  
                // to ignore the exception and continue enumerating the remaining files and  
                // folders. It is also possible (but unlikely) that a DirectoryNotFound exception  
                // will be raised. This will happen if currentDir has been deleted by 
                // another application or thread after our call to Directory.Exists. The  
                // choice of which exceptions to catch depends entirely on the specific task  
                // you are intending to perform and also on how much you know with certainty  
                // about the systems on which this code will run. 
                catch (UnauthorizedAccessException e)
                {
                    Console.WriteLine(e.Message);
                    continue;
                }
                catch (System.IO.PathTooLongException e)
                {
                    Console.WriteLine(e.Message + " : " + currentDir);
                    continue;
                }
                catch (System.IO.DirectoryNotFoundException e)
                {
                    Console.WriteLine(e.Message);
                    continue;
                }

                string[] files = null;
                try
                {
                    files = System.IO.Directory.GetFiles(currentDir, "*.lnk");
                }
                catch (System.IO.PathTooLongException e)
                {
                    Console.WriteLine(e.Message + " : " + currentDir);
                    continue;
                }
                catch (UnauthorizedAccessException e)
                {
                    Console.WriteLine(e.Message);
                    continue;
                }
                catch (System.IO.DirectoryNotFoundException e)
                {
                    Console.WriteLine(e.Message);
                    continue;
                }
                // Perform the required action on each file here. 
                // Modify this block to perform your required task. 
                foreach (string file in files)
                {
                    try
                    {
                        // Perform whatever action is required in your scenario.
                        System.IO.FileInfo fi = new System.IO.FileInfo(file);
                        lstFilesFound.Add(fi.FullName);
                    }
                    catch (System.IO.PathTooLongException e)
                    {
                        Console.WriteLine(e.Message + " : " + file);
                        continue;
                    }
                    catch (System.IO.FileNotFoundException e)
                    {
                        // If file was deleted by a separate application 
                        //  or thread since the call to TraverseTree() 
                        // then just continue.
                        Console.WriteLine(e.Message);
                        continue;
                    }
                }

                // Push the subdirectories onto the stack for traversal. 
                // This could also be done before handing the files. 
                foreach (string str in subDirs)
                    dirs.Push(str);

            }
        }
    }
}

Open in new window


The XAML file I tested with
<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" >
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <ListBox ItemsSource="{Binding}" />
        <Button Grid.Column="1" x:Name="Button3" Content="Find lnk Files" Click="Button3_Click" />
    </Grid>
</Window>

Open in new window

0
 

Author Comment

by:TeknikDev
Comment Utility
Im still getting errors  in Visual Studio 2010 for C# WPF

Error      1      The type or namespace name 'ObservableCollection' could not be found (are you missing a using directive or an assembly reference?)      C:\visual studio 2010\Projects\WpfApplication2\WpfApplication2\MainWindow.xaml.cs      31      58      WpfApplication2

 Error      2      Cannot implicitly convert type 'ObservableCollection<string>' to 'object'      c:\visual studio 2010\Projects\WpfApplication2\WpfApplication2\MainWindow.xaml.cs      27      32      WpfApplication2
0
 
LVL 62

Expert Comment

by:Fernando Soto
Comment Utility
When I created the test project the using statement for that library was included by default. If this using statement is missing add it to the list.

using System.Collections.ObjectModel
0
 

Author Comment

by:TeknikDev
Comment Utility
This worked! Thank you very much sir!
0
 
LVL 62

Expert Comment

by:Fernando Soto
Comment Utility
Not a problem, glad to help.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now