0

Listing all files in a drive other than my system drive throws an UnauthorizedAccessException.

How can I solve this problem?

Is there a way to grant my application the access it needs?


My code:

Directory.GetFiles("S:\\", ...)
Community
  • 1
  • 1
Joan Venge
  • 315,713
  • 212
  • 479
  • 689

4 Answers4

2

Here's a class that will work:

public static class FileDirectorySearcher
{
    public static IEnumerable<string> Search(string searchPath, string searchPattern)
    {
        IEnumerable<string> files = GetFileSystemEntries(searchPath, searchPattern);

        foreach (string file in files)
        {
            yield return file;
        }

        IEnumerable<string> directories = GetDirectories(searchPath);

        foreach (string directory in directories)
        {
            files = Search(directory, searchPattern);

            foreach (string file in files)
            {
                yield return file;
            }
        }
    }

    private static IEnumerable<string> GetDirectories(string directory)
    {
        IEnumerable<string> subDirectories = null;
        try
        {
            subDirectories = Directory.EnumerateDirectories(directory, "*.*", SearchOption.TopDirectoryOnly);
        }
        catch (UnauthorizedAccessException)
        {
        }

        if (subDirectories != null)
        {
            foreach (string subDirectory in subDirectories)
            {
                yield return subDirectory;
            }
        }
    }

    private static IEnumerable<string> GetFileSystemEntries(string directory, string searchPattern)
    {
        IEnumerable<string> files = null;
        try
        {
            files = Directory.EnumerateFileSystemEntries(directory, searchPattern, SearchOption.TopDirectoryOnly);
        }
        catch (UnauthorizedAccessException)
        {
        }

        if (files != null)
        {
            foreach (string file in files)
            {
                yield return file;
            }
        }
    }
}

You can the use it like this:

IEnumerable<string> filesOrDirectories = FileDirectorySearcher.Search(@"C:\", "*.txt");

foreach (string fileOrDirectory in filesOrDirectories)
{
   // Do something here.
}

It's recursive, but the use of yield gives it a low memory footprint (under 10KB in my testing). If you want only files that match the pattern and not directories as well just replace EnumerateFileSystemEntries with EnumerateFiles.

JamieSee
  • 12,696
  • 2
  • 31
  • 47
  • Can it find a specific file? I tried it and in the // Do something here, I put Messagebox.show(fileOrDirectory) and nothing came up. I know for a fact that the file exists. The filename does contain spaces and is longer than 8 characters. Does that matter? – Cocoa Dev Mar 17 '13 at 06:06
1

In .net core you can do something like this below. It can search for all subdirectories recursively with good performance and ignoring paths without access. I also tried other methods found in How to quickly check if folder is empty (.NET)? and Is there a faster way than this to find all the files in a directory and all sub directories? and https://www.codeproject.com/Articles/1383832/System-IO-Directory-Alternative-using-WinAPI

public static IEnumerable<string> ListFiles(string baseDir)
{
    EnumerationOptions opt = new EnumerationOptions();
    opt.RecurseSubdirectories = true;
    opt.ReturnSpecialDirectories = false;
    //opt.AttributesToSkip = FileAttributes.Hidden | FileAttributes.System;
    opt.AttributesToSkip = 0;
    opt.IgnoreInaccessible = true;

    var tmp = Directory.EnumerateFileSystemEntries(baseDir, "*", opt);
    return tmp;
}
1

Are you allowed to access the drive? Can the program access the drive when it's not run from Visual Studio? Are restrictive permissions defined in the project's Security page ("Security Page, Project Designer")?

ChrisW
  • 54,973
  • 13
  • 116
  • 224
0

I solved the problem. Not really but at least the source.

It was the SearchOption.AllDirectories option that caused the exception.

But when I just list the immediate files using Directories.GetFiles, it works.

This is good enough for me.

Any way to solve the recursive listing problem?

Joan Venge
  • 315,713
  • 212
  • 479
  • 689