UnauthorizedAccessException从LOCALAPPDATA中的File.ReadAllBytes“拒绝访问路径”

在读取%LOCALAPPDATA%内的文件时,同一台机器的同一用户间歇性地发生此exception。

研究

我已经检查了这个标题目前提供的所有可能的重复项(有很多)。 有一个与读取没有答案的AES加密文件有关; 我不相信,因为这些文件没有加密。

其中大部分与编写文件有关(但我正在读取文件),或者是MSDN上针对File.ReadAllBytes(字符串)记录的明显原因。

这个例外的三个解释是:

  1. “当前平台不支持此操作” – 我不知道这意味着什么; 但鉴于这有时适用于同一台机器上的同一用户(我将在下面解释),我想我可以排除这种情况。
  2. path指定了一个目录” – 正如你从下面的代码中看到的那样,调用是在File.Exists的检查中File.Exists ,所以我想我可以排除这一点。
  3. “来电者没有所需的许可。” 这是这个例外的常见解释,我怀疑我得到了某种“边缘情况”。

脚本

当以域用户身份运行的应用程序正在读取同一用户的%LOCALAPPDATA%子文件夹内的文件时,会发生这种情况(对于该用户来说,应该没有权限问题来读取文件)。 其中的子文件夹只遵循正常的“CompanyName”\“ApplicationName”结构,并且没有对子文件夹应用其他权限(我们只是使用该文件夹来保持我们的文件远离其他人)。

例外

System.UnauthorizedAccessException:拒绝访问路径’ [redacted] ‘。 在System.IO .__ Error.WinIOError(Int32 errorCode,String maybeFullPath)at System.IO.FileStream.Init(String path,FileMode mode,FileAccess access,Int32 rights,Boolean useRights,FileShare share,Int32 bufferSize,FileOptions options,SECURITY_ATTRIBUTES secAttrs) ,System msgPath,Boolean bFromProxy,Boolean useLongPath,Boolean checkHost)at System.IO.FileStream..ctor(String path,FileMode mode,FileAccess access,FileShare share,Int32 bufferSize,FileOptions options,String msgPath,Boolean bFromProxy,Boolean useLongPath, System.IO.File.InternalReadAllBytes(String path,Boolean checkHost)中的Boolean checkHost)
下面的代码

  // Note that filename is within %LOCALAPPDATA% if (File.Exists(fileName)) { var readAllBytes = File.ReadAllBytes(fileName); // exception here // etc... } 

certificate它是断断续续的

我可以通过我们的错误日志和大多数时间工作的其他信息的组合来certificate,我可以为机器和用户的特定组合certificate以下事件序列:

  • 然后,应用程序工作
  • 发生此exception(可能是几次,每次重试延迟呈指数级增加:1分钟,2分钟,4分钟等),然后
  • 该应用程序再次工作

我不相信文件系统会发生任何重大更改(例如权限)以便修复它。 我想知道这是否可能是由边缘权限问题引起的,例如,如果他们的密码即将过期,或者最近已被更改。

我有一个具体的例子,当我注意到这个错误发生时,我建议用户重启他们的机器,问题就消失了。

任何人都可以给我一个权威的解释原因,超出我已经猜到的,或确认它是什么?

这个问题太广泛了,但我想指出除了你列出之外还有其他原因可以拒绝访问。 例如,考虑这个简单的程序:

 public class Program { static string _target = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "test", "test.txt"); static void Main(string[] args) { File.Create(_target).Dispose(); ProcessFile(); // below throws access denied if (File.Exists(_target)) Console.WriteLine(File.ReadAllText(_target)); Console.ReadKey(); } static void ProcessFile() { // open and abandon handle var fs = new FileStream(_target, FileMode.Open, FileAccess.Read, FileShare.Delete); // delete File.Delete(_target); } } 

在这里,我们在%LOCALAPPDATA%下创建新文件,并使用FileShare.Delete打开它,但不关闭。 FileShare.Delete允许后续删除文件,但在关闭文件的所有句柄之前,文件不会被实际删除。

然后我们继续使用File.Delete ,它实际上并没有删除文件,而是将其标记为删除,因为我们仍然有打开文件句柄。

现在, File.Exists为此类文件返回true,但尝试访问它会引发“Access denied”exception,如您所述。

这种具体情况是否与您的案件相关很难说,但可能是这样。

我的观点主要是:你应该期望这样的例外(以及“已经在使用中的文件”类型的例外)并通过重试来处理它们。 它们可能由于您无法控制的各种原因而发生。