2011-06-24 173 views
11

这是一个有点棘手一个,所以我承担......System.UnauthorizedAccessException的 - 访问路径被拒绝

我有一个简单的小方法:

Public Overloads Shared Function DoStuff(ByVal path As String) As Boolean 
     If Not IO.File.Exists(ipath) Then Throw New ArgumentException 

     Dim result As Boolean 
     Using fs As FileStream = New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read) 
      ' do stuff here, details are not important 
      fs.Close() 
     End Using 

     Return result 
    End Function 

我明白,该方法不显示如何使用流,但细节无关紧要,下面将对此进行解释。

此方法坐在一个类库中,一个帮手我们在各种其他项目中引用。显然,大部分代码应该看起来很好,假设路径是有效的,可访问的等。

现在,问题。我有一个WCF服务库引用并使用上述方法中的Helper程序集。 WCF服务库托管在Windows服务中,而Windows服务又驻留在我们的一台服务器上。 WCF服务具有接收文件的UNC路径的操作,并且在正常流程中,在辅助类中调用上述方法。

我发送的路径是针对我们网络上的共享文件。 “使用fs为...”失败,但有以下例外:

System.UnauthorizedAccessException:访问路径'我的文件路径在这里列出'被拒绝。 (System.IO.FileStream.Init(String path,FileMode mode,FileAccess access,Int32 rights,Boolean useRights,FileShare share,Int32 bufferSize,FileOptions选项,SECURITY_ATTRIBUTES secAttrs)上System.IO.__错误.WinIOError(Int32错误码,字符串maybeFullPath) ,字符串msgPath,布尔bFromProxy,布尔useLongPath)System.IO.FileStream上的System.IO.FileStream ..(String路径,FileMode模式,FileAccess访问,FileShare共享,Int32 bufferSize,FileOptions选项,字符串msgPath,布尔bFromProxy) ..(串路径,FileMode模式)在MyHelperAssemblyName。DoStuff(字符串文件路径)在异常的其余部分是一个堆栈跟踪指向方法,组件,WCF服务等

现在,事情我已经尝试来诊断问题的列表(包括愣神明显的步骤):

  • 复制和粘贴)在堆栈跟踪到Windows资源管理器(包括我的本地计算机和服务器上列出的路径,以确保文件存在并且可访问 - >能够访问该文件
  • 确保Windows服务的帐户具有足够的文件权限阅读 - >有效权限列出该服务的帐户为完全控制
  • 更改Windows服务的帐户以使用我的个人管理帐户(临时措施),并明显重新启动服务以使更改生效 - >相同代码行失败
  • 将包含该文件的目录复制到本地计算机,并对本地计算机运行服务(我们希望确保承载文件的NAS不是原因) - >The同一行代码失败
  • 创建一个快速控制台应用程序,将辅助程序集的方法中的代码复制粘贴到应用程序,注入相同的文件路径,运行它在本地,然后在服务器上(通过在服务器上,我的意思是远程连接到服务器使用我前面提到的相同的管理员帐户,并运行它) - >该应用程序运行代码没有问题
  • 创建一个控制台应用程序,并使用在控制台应用程序中托管WCF服务库的bulk standard方式。在本地运行应用程序,然后使用WcfStorm针对我指定为控制台应用程序的基址的本地地址,调用与正常服务失败相同的路径的相同方法 - >WcfStorm的结果证实代码没有问题
  • 仔细检查WCF服务库的代码,以确保没有任何特殊的条件逻辑会影响我的测试 - >Helper方法在服务操作实现开始后几乎立即被调用(只是参数验证后)。操作无法通过辅助方法返回相关结果,因此,当我以前一直收到一致的结果并假定“怪异”文件访问代码已经运行时,它实际上已经运行了
  • Re - 部署了Windows服务主机,WCF服务库和Helper Assembly的干净重建服务(希望确保我屏幕上的代码实际上是服务器上运行的代码) - >没有变化
  • 编辑2011-06-24 16:32GMT - 使用我之前创建的控制台应用程序托管WCF服务,相应地调整baseAddress并在服务器上部署。如上所述使用相同的管理员帐户运行应用程序。使用WcfStorm测试新基地址上的新应用程序。 - >代码工作正常,并返回了良好的效果
  • 编辑2011-06-27 10:21GMT - 创建一个简单的(我相信在这个阶段缩小它归结为是Windows服务的错?) Windows服务,引用辅助类。安装在服务器上,该服务的帐户设置为与Live Server相同。 - >新的服务能够运行的代码和访问文件
  • 编辑2011-06-27 10:23GMT - 恼火,服务工作过,我拉着我离开了运行开放WcfStorm整个周末。从星期五起,结果仍显示现场服务失败。我反感了同样的要求 - >它的工作...现在我其实更恼火,因为我有跟踪问题

    所以,服务是现在正常工作没有真正的手段。任何人有任何想法会导致这种间歇性失败?我向同事保证周末没有任何变化(至少不是手动变化)。挡板...

+1

此外,作为一个轻微的另外,我是99.99999%,我目前有问题的文件,昨晚工作。该服务实际上在另一个文件(进一步在提供的路径的循环中)上失败,昨晚发生同样的错误。 I.E.我有一个字符串列表{“PathA”,“PathB”,“PathC”}。昨天晚上,PathA成功了,PathB失败并出现了上述错误。今天,PathA失败了,我没有达到PathB。我没有把这个直接放在OP中,因为它只是简单地混淆了这个问题...... – Smudge202

+1

我认为这个“网络共享”和本地机器不在同一个域上? – insipid

+1

@insipid:所有相同的域。本地机器是我的开发机器在工作。服务器是楼下的机器之一。 NAS与服务器坐在同一个房间里(物理上)。全部在相同的LAN上,全部在同一个域上。不知道你为什么问,但如果是因为我测试了NAS - NAS有一个硬编码的25同时连接限制,所以想要消除这是一个原因。 – Smudge202

回答

1

当我的代码访问尚未完全写入磁盘的新文件时,我有类似的东西。所以等几毫秒就为我解决了。在完全写入磁盘之前,是否有可能试图读取该流?

+1

不幸的是,不是。我碰巧知道这个文件已经在这个网络共享上呆了4年多了。但是,我能够从2个独立的位置打开该文件,将该文件复制到本地PC,并使用测试项目以代码访问该文件,以确认该流是否可用。感谢您的建议,尽管 – Smudge202

4

尝试process monitor。它会显示用户正在访问该文件以及正在返回的特定Windows错误代码。那么你应该能够看出它为什么对某些文件而不是其他文件起作用。

+1

我会尝试下一次我抓到一个文件玩愚蠢的鸡编。感谢@Mike – Smudge202

1

您的WCF服务是否使用模拟?

这将解释为什么新的Windows服务可以执行操作,但WCF服务不能。新服务直接针对NAS进行身份验证。如果在旧服务中,WCF模拟调用者,客户端计算机将对用户进行身份验证,将他们的令牌传递给WCF服务,WCF服务又将安全令牌传递给NAS,并且您遇到double hop问题。

您可以主动安全上下文回复到服务帐户像this

using (WindowsIdentity.Impersontate(IntPtr.Zero)) 
{ 
    DoStuff(); 
} 

当然,这并不能解释为什么它可能已经工作间歇。但是它会解释WCF服务在托管它的机器上本地调用时工作,但不能从远程客户端机器上调用。

+1

嗨,亚历克斯,我认为同样的事情。 WCF服务不使用模拟,但我确实想知道服务帐户可能会产生什么影响。这就是为什么在我的测试中,我将账户更改为管理员,但似乎没有任何影响。尽管感谢链接! – Smudge202

+0

如果这是一个双跳问题,作为管理员(域管理员)将无济于事。也许你已经试过了,但是如果你从托管它的计算机上调用WCF服务,它会工作吗? –

+1

是的,我的一个测试是在控制台应用程序中托管WCF服务库(正常的MSDN方式)。然后,我将该主机放在同一台服务器上并启动它。使用WcfStorm我调用了新托管的WCF服务,代码工作正常。奇怪,呵呵! – Smudge202

1

我有几个臀部。

您是否尝试将'FileAccess.Read'和/或'FileShare.Read'设置为'ReadWrite'?

此外,这种警告可能是一个因素吗?从http://msdn.microsoft.com/en-us/library/5h0z48dh.aspx

注意

当你编译一组字符 与特定的文化背景和 检索与 不同文化背景的相同的字符,该 字符可能不解释, 和可能导致抛出异常为 。

+1

感谢您的回答。我将它设置为Read,因为该文件仅用于读取。坦率地说,当我设置这些枚举时,我不承认知道底层的内容 - 我认为它与SQL Server中的锁类型很相似。下一次我遇到这个问题时,我会尝试将Enum设置为ReadWrite,只是出于好奇。关于文化,我没有考虑过。我不会在任何地方设置文化,并且服务器能够运行代码,但不在服务+ WCF环境中。 – Smudge202