Solved

Searching for file in all folders using C#

Posted on 2014-01-03
17
1,594 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
[Live Webinar] The Cloud Skills Gap

As Cloud technologies come of age, business leaders grapple with the impact it has on their team's skills and the gap associated with the use of a cloud platform.

Join experts from 451 Research and Concerto Cloud Services on July 27th where we will examine fact and fiction.

 

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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

635 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