【问题标题】:C# - Cannot access all filesC# - 无法访问所有文件
【发布时间】:2012-10-17 22:16:24
【问题描述】:

我的应用程序使用 .NET 对象 Directory.GetFiles()

我使用的实际重载是

var allFiles = Directory.GetFiles("C:\\Users\\Dave", "*.*", SearchOption.AllDirectories);

问题是当源文件夹是 C:\Users\UserName 时,它​​会尝试查看应用程序数据文件夹。

当它尝试从应用程序数据文件夹中读取时,会抛出异常:

"访问路径'C:\Users\Dave\AppData\Local\Application 数据'被拒绝。”

所以,我的问题是有人对我的选择有意见吗?我假设我必须改变我收集所有文件的方式,或者可能有一个内置的重载或方法可以让我继续这个(我显然不知道)。

如果有帮助,这样做的目的是获取Directory.GetFiles() 检索到的所有文件并将它们“粘贴”到其他地方(美化的复制和粘贴/备份)。我其实并不太担心系统文件,只是“用户文件”。

【问题讨论】:

  • 您的程序在哪个帐户下运行?
  • 好问题 - 目前,这在我的家用电脑上 - 这是我的帐户,我是拥有完全权限的管理员。虽然我不知道我的程序是否以完全权限运行,因为我在调试模式下运行 VS(准确地说,使用 MS TESTS)
  • 如果您以管理员身份运行 Visual Studio(右键单击 > 以管理员身份运行),它可以工作吗?
  • @SimonWhitehead;很好的建议,但遗憾的是,同样的错误仍然存​​在。

标签: c# exception permissions file-permissions


【解决方案1】:

目录%AppData% 是受系统保护的目录。一旦访问未被授权(来自管理员以外的其他用户的访问),Windows 将尝试阻止对该目录的任何访问。

默认情况下,只有管理员才有权限读取/写入此目录。

或者,您可以捕获异常并查看结果是否为Access Denied。然后,您可能会提示用户以管理员身份运行以完成此步骤。这是一个提示用户以管理员身份运行的简单示例

try
{
     var allFiles = Directory.GetFiles("C:\\Users\\Dave", "*.*", SearchOption.AllDirectories);
}
catch (Exception EX)
{
     if (EX.Message.ToLower().Contains("is denied."))
     {
          ProcessStartInfo proc = new ProcessStartInfo();
          proc.UseShellExecute = true;
          proc.WorkingDirectory = Environment.CurrentDirectory;
          proc.FileName = Application.ExecutablePath;
          proc.Verb = "runas"; //Required to run as Administrator
          try
          {

          Process.Start(proc);

          }
          catch
          {
               //The user refused to authorize
          }
     }
}

但是,当您的应用程序启动时,您可能总是提示用户进行授权,这并不总是推荐的。为此,您必须编辑您的项目app.manifest 文件

找到并更改以下行

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

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

谢谢,
希望对您有所帮助 :)

【讨论】:

  • 好的,这就是我的猜测,但无法确定,所以谢谢,这是非常好的细节。我想知道是否最好使用 Environment.GetSpeicalFolder() 方法查看文件路径是否与 %appdata% 文件夹匹配,如果匹配,则跳过它,因为我不想尽可能依赖捕获! +1
  • @DaveRook 你也可以使用它! Environment.ExpandEnvironmentVariables("%AppData%"); 但我并不认为这是一个好的编程习惯。您可以随时提示用户授权,如果他拒绝,您可以跳过处理此文件夹。祝你有美好的一天:)
  • 对不起,我打算使用 if (Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).Contains(sourceFolder)) .. 但是,我很感激可能有很多我必须使用设置为:S
  • @DaveRook 很抱歉造成误解,很高兴您找到了解决问题的方法。祝您设置应用程序好运。祝你有美好的一天:)
【解决方案2】:

最好使用 foreach 循环来获取您可以访问的文件夹名称:

DirectoryInfo dI = new DirectoryInfo(@"C:\Users\Dave");
List<string> files = new List<string>();
foreach (DirectoryInfo subDI in dI.GetDirectories())
{
        if ((subDI.Attributes & (FileAttributes.ReparsePoint | FileAttributes.System)) !=
        (FileAttributes)0)
              continue;
        files.Add(subDI.FullName);
}

【讨论】:

  • 谢谢,这对我的应用程序来说可能是更好的方法。谢谢+1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-07
  • 2020-11-19
相关资源
最近更新 更多