Access to the path is denied when using Directory.GetFiles(...) [duplicate]

I'm running the code below and getting exception below. Am I forced to put this function in try catch or is there other way to get all directories recursively? I could write my own recursive function to get files and directory. But I wonder if there is a better way.

// get all files in folder and sub-folders
var d = Directory.GetFiles(@"C:\", "*", SearchOption.AllDirectories);

// get all sub-directories
var dirs = Directory.GetDirectories(@"C:\", "*", SearchOption.AllDirectories);

"Access to the path 'C:\Documents and Settings\' is denied."


Solution 1:

If you want to continue with the next folder after a fail, then yea; you'll have to do it yourself. I would recommend a Stack<T> (depth first) or Queue<T> (bredth first) rather than recursion, and an iterator block (yield return); then you avoid both stack-overflow and memory usage issues.

Example:

    public static IEnumerable<string> GetFiles(string root, string searchPattern)
    {
        Stack<string> pending = new Stack<string>();
        pending.Push(root);
        while (pending.Count != 0)
        {
            var path = pending.Pop();
            string[] next = null;
            try
            {
                next = Directory.GetFiles(path, searchPattern);                    
            }
            catch { }
            if(next != null && next.Length != 0)
                foreach (var file in next) yield return file;
            try
            {
                next = Directory.GetDirectories(path);
                foreach (var subdir in next) pending.Push(subdir);
            }
            catch { }
        }
    }

Solution 2:

You can set the program so you can only run as administrator.

In Visual Studio:

Right click on the Project -> Properties -> Security -> Enable ClickOnce Security Settings

After you clicked it, a file will be created under the Project's properties folder called app.manifest once this is created, you can uncheck the Enable ClickOnce Security Settings option

Open that file and change this line :

<requestedExecutionLevel level="asInvoker" uiAccess="false" />

to:

 <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />

This will make the program require administrator privileges, and it will guarantee you have access to that folder.

Solution 3:

Well, you either avoid the directories for which you don't have permissions, or you don't but then respond gracefully when access is denied.

If you choose the first option, you will need to make sure that you know what directories they are, and also that the permissions for the thread's identity do not change. This is tricky and prone to error; I wouldn't recommend it for a production-quality system.

The second option looks more appropriate. Use a try/catch block and skip any "forbidden" directories.

Solution 4:

You can achieve this by using EnumerationOptions for the third argument. This class provides a property called IgnoreInaccessible which toggles whether an exception will be thrown if an inaccessbile file/folder is encountered.

Other properties related to searching are available too, see: EnumerationOptions Class (System.IO)


Example:

var options = new EnumerationOptions()
{
    IgnoreInaccessible = true
};

var files = Directory.GetFiles("mypath", "*.*", options);

foreach (var file in files)
{
    // File related activities
}

Note: IgnoreAccessible is set to true by default, but I've included it in the example above for visibility purposes.