【问题标题】:Solving UnauthorizedAccessException issue for listing files解决列出文件的 UnauthorizedAccessException 问题
【发布时间】:2010-11-02 22:01:32
【问题描述】:

列出系统驱动器以外的驱动器中的所有文件会引发UnauthorizedAccessException

我该如何解决这个问题?

有没有办法授予我的应用程序所需的访问权限?


我的代码:

Directory.GetFiles("S:\\", ...)

【问题讨论】:

  • 您签署了您的申请吗?您的安全设置是什么?
  • 不,我没有。我只是为自己写这个应用程序。
  • 什么类型的应用程序?表格? ASP.NET?可以发一些代码吗?
  • 谢谢,这是winforms。我会回复详细信息。

标签: c# .net security exception


【解决方案1】:

这是一个可以工作的类:

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

你可以这样使用它:

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

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

它是递归的,但是使用 yield 使它的内存占用很低(在我的测试中不到 10KB)。如果您只想要与模式匹配的文件而不是目录,只需将 EnumerateFileSystemEntries 替换为 EnumerateFiles

【讨论】:

  • 它能找到特定的文件吗?我试过了,在 // Do something here 中,我放了 Messagebox.show(fileOrDirectory) 并没有出现。我知道该文件存在的事实。文件名包含空格且长度超过 8 个字符。这有关系吗?
【解决方案2】:

是否可以访问该驱动器?程序不从 Visual Studio 运行时可以访问驱动器吗?项目的安全页面(“Security Page, Project Designer”)中是否定义了限制性权限?

【讨论】:

  • 是的,我启用了单击一次安全 > 完全信任应用程序。够了吗?
【解决方案3】:

我解决了这个问题。不是真的,但至少是来源。

是 SearchOption.AllDirectories 选项导致了异常。

但是当我只使用 Directories.GetFiles 列出即时文件时,它可以工作。

这对我来说已经足够了。

有什么办法可以解决递归列表问题?

【讨论】:

    【解决方案4】:

    在 .net 核心中,您可以执行以下操作。它可以递归搜索所有子目录,性能良好,无需访问即可忽略路径。 我还尝试了其他方法 How to quickly check if folder is empty (.NET)?Is there a faster way than this to find all the files in a directory and all sub directories?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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多