这是一个稍微棘手的问题,所以请耐心等待...
我有一个简单的小方法:
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 服务库,它引用并使用上述助手程序集中的方法。WCF 服务库托管在一个 Windows 服务中,而该 Windows 服务又驻留在我们的一台服务器上。WCF 服务有一个操作,接收一个 UNC 路径用于文件,在正常流程中,调用上面助手类中的方法。
我发送的路径是网络上的共享文件的路径。"Using fs As..." 这一行失败,并抛出以下异常:
System.UnauthorizedAccessException: 访问路径 "我的文件路径在此列出" 被拒绝。 at 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, String msgPath, Boolean bFromProxy, Boolean useLongPath) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy) at System.IO.FileStream..ctor(String path, FileMode mode) at MyHelperAssemblyName.DoStuff(String filePath) in 异常的其余部分是指向方法、程序集、WCF 服务等的堆栈跟踪"
现在,我列出了一些为诊断问题所尝试的事情(包括愚蠢明显的步骤)的清单:
将Stack Trace中列出的路径复制并粘贴到Windows Explorer中(本地计算机和服务器上都要这样做),以确保文件存在且可访问-->能够访问该文件
确保Windows服务帐户对文件具有足够的读取权限-->有效权限将服务帐户列为具有完全控制权
更改Windows服务帐户以使用我的个人管理员帐户(临时措施),并显然重新启动服务以使更改生效-->相同的代码行失败
复制包含文件的目录到我的本地计算机,并针对我的本地计算机运行服务(我们想确保托管文件的NAS不是原因)-->相同的代码行失败
创建一个快速控制台应用程序,将辅助程序集方法中的代码复制并粘贴到应用程序中,注入相同的文件路径,在本地计算机上运行,然后在服务器上运行(通过在服务器上远程连接使用我之前提到的相同管理员帐户,并运行它)-->应用程序运行代码没有任何问题
创建控制台应用程序,并使用bulk standard方式在控制台应用程序中托管WCF服务库。在本地运行应用程序,然后使用WcfStorm针对我指定为控制台应用程序基地址的本地地址调用相同的方法和路径,正常服务无法运行-->来自WcfStorm的结果确认代码没有问题
仔细检查WCF服务库的代码,以确保没有任何奇怪的条件逻辑会影响我的测试-->帮助方法几乎是在服务操作实现开始时立即调用的(在参数验证之后)。操作不可能在运行辅助方法之前返回连贯的结果,因此当我之前收到连贯的结果并假设已运行“奇怪”的文件访问代码时,它实际上已经运行了
重新部署服务,使用Windows服务主机、WCF服务库和辅助程序集的干净重建(希望确保屏幕上的代码实际上是在服务器上运行的代码)-->没有变化
EDIT 2011-06-24 16:32GMT - 使用我之前创建的控制台应用程序托管WCF服务,相应地调整baseAddress并在服务器上部署。使用与上述相同的管理员帐户运行应用程序。在新的基地址上使用WcfStorm测试新应用程序-->代码按预期工作并返回良好结果(我认为此时将其缩小到是Windows服务的故障?)
EDIT 2011-06-27 10:21GMT - 创建一个简单的Windows服务,引用辅助类。安装在服务器上,服务的帐户设置为与Live Server相同。-->新服务能够运行代码并访问文件
EDIT 2011-06-27 10:23GMT - 愤怒于服务已经起作用,我打开了WcfStorm,它一直在周末运行。结果仍然显示从星期