Solved

Searching for file in all folders using C#

Posted on 2014-01-03
17
1,548 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
17 Comments
 
LVL 22

Expert Comment

by:Ivo Stoykov
ID: 39753566
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
ID: 39753567
Better use

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

Author Comment

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

Open in new window

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:TeknikDev
ID: 39753958
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 63

Expert Comment

by:Fernando Soto
ID: 39758469
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
ID: 39759499
Hey Fernando, can you provide the actual code on how to do this? Thanks
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 39759531
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
ID: 39759547
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
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 39761216
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
ID: 39761975
Ok ill give it a whirl, I'll replace the Console.Writeline with MessageBox.Show.
0
 

Author Comment

by:TeknikDev
ID: 39762042
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 63

Accepted Solution

by:
Fernando Soto earned 500 total points
ID: 39762870
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
ID: 39763024
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 63

Expert Comment

by:Fernando Soto
ID: 39763155
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
ID: 39763387
This worked! Thank you very much sir!
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 39763405
Not a problem, glad to help.
0

Featured Post

Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …

734 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