UnauthorizedAccessException从LOCALAPPDATA

时间:2018-04-27 08:46:19

标签: c# windows unauthorizedaccessexcepti

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

研究

我已经检查了这个标题目前提供的所有可能的副本(有很多)。有一个与reading an AES encrypted file无关,没有答案;我认为不适用,因为这些文件没有加密。

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

这个例外的三个解释是:

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

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

    异常

      

    System.UnauthorizedAccessException:访问路径' [编辑] '是   否认。在System.IO .__ Error.WinIOError(Int32 errorCode,String   maybeFullPath)at System.IO.FileStream.Init(String path,FileMode   模式,FileAccess访问,Int32权限,布尔useRights,FileShare   share,Int32 bufferSize,FileOptions选项,SECURITY_ATTRIBUTES   secAttrs,String msgPath,Boolean bFromProxy,Boolean useLongPath,   System.IO.FileStream..ctor(String path,Boolean checkHost)   FileMode模式,FileAccess访问,FileShare共享,Int32 bufferSize,   FileOptions选项,String msgPath,Boolean bFromProxy,Boolean   useLongPath,Boolean checkHost)at   System.IO.File.InternalReadAllBytes(String path,Boolean checkHost)
      在下面的代码

    代码

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

    证明它是断断续续的

    我可以通过我们的错误日志和其他信息的组合来证明这一点的时间,并且我可以证明特定组合机器的以下事件序列用户:

    • 该应用程序有效,然后
    • 发生此异常(可能多次,每次重试延迟呈指数级增长:1分钟,2分钟,4分钟等),然后
    • 该应用程序再次运行

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

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

    问题

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

1 个答案:

答案 0 :(得分:1)

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

var somejson = "[{ \"key1\" : \"<header class='main-header dark-bg'><div class='row'></div></header>\"},{\"key2\" : \"<div class='row content clearfix worldwide dark-bg t--bg-5'></div>\"}]";

我们在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对于此类文件返回true,但尝试访问它会抛出&#34;访问被拒绝&#34;如你所描述的例外。

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

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