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

Ric*_*imo 6 c# windows unauthorizedaccessexcepti

在读取其中的文件时,同一台机器的同一用户间歇性地发生此异常%LOCALAPPDATA%.

研究

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

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

这个例外的三个解释是:

  1. "当前平台不支持此操作" - 我不知道这意味着什么; 但鉴于这有时适用于同一台机器上的同一用户(我将在下面解释),我想我可以排除这种情况.
  2. " path指定了一个目录" - 正如你从下面的代码中看到的那样,调用是在一个检查中进行的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,布尔checkHost)在System.IO.File.InternalReadAllBytes(字符串路径,布尔checkHost)
下面的代码

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

证明它是断断续续的

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

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

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

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

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

Evk*_*Evk 1

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

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);
    }        
}  
Run Code Online (Sandbox Code Playgroud)

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

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

现在,File.Exists对于此类文件返回 true,但尝试访问它会抛出“访问被拒绝”异常,如您所描述的。

很难判断这种具体情况是否与您的案例相关,但可能是。

我的观点主要是:您应该预料到此类异常(以及“文件已在使用”类型的异常)并通过重试来处理它们。它们的发生可能出于您无法控制的各种原因。