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

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.


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.


It has already been pointed out that you need to do it yourself so I thought I'd share my solution which avoids collections along the way. It should be noted that this will ignore all errors not just AccessDenied. To change that you can just make the catch blocks more specific.

    IEnumerable<string> GetFiles(string folder, string filter, bool recursive)
    {
        string [] found = null;
        try
        {
            found =  Directory.GetFiles(folder, filter);
        }
        catch { }
        if (found!=null)
            foreach (var x in found)
                yield return x;
        if (recursive)
        {
            found = null;
            try
            {
                found = Directory.GetDirectories(folder);
            }
            catch { }
            if (found != null)
                foreach (var x in found)
                    foreach (var y in GetFiles(x, filter, recursive))
                        yield return y;
        }
    }

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 { }
        }
    }

Tags:

C#