1

我正在尝试使用此问题的最流行答案中的代码:使用 C#,如何确定哪个进程锁定了文件?

我正在使用 VS2010 和 .NET v4 在 Windows 7 x64 中测试此代码。

我发现代码摘录...

var baTemp = new byte[nLength];
try
{
    Marshal.Copy(ipTemp, baTemp, 0, nLength);
    strObjectName = Marshal.PtrToStringUni(Is64Bits() ? new IntPtr(ipTemp.ToInt64()) : new IntPtr(ipTemp.ToInt32()));
}
catch (AccessViolationException)
{
    return null;
}
finally
{
    Marshal.FreeHGlobal(ipObjectName);
    Win32API.CloseHandle(ipHandle);
}

是什么导致我的问题。当之前创建的地址无效时,Marshal.Copy 可能会失败。在 x64 系统中创建地址的代码...

if (Is64Bits())
{
    ipTemp = new IntPtr(Convert.ToInt64(objObjectName.Name.Buffer.ToString(), 10) >> 32);
}

在我提到的失败的一个实例中,从 20588995036390572032 的缓冲区字符串表示开始,它转换为 x1C92AA2089E00000。该代码似乎去除了低位字,将 x1C92AA20 作为可用地址。

问题 1:为什么我们不简单地使用缓冲区对象提供的 64 位地址,而不是在 64 位操作系统上运行的 64 位应用程序中移出低位字并仅使用高位字?

问题 2:try/catch/finally 块是否应该不仅仅包含 AccessViolationException?

4

1 回答 1

0

阅读对该文章的评论。不可行的代码。不工作。不要使用。即使是“建议的”更正版本也被破坏了(它在我的 Win8 64 位上不起作用),用它的作者的话来说:

以下是基于 Iain Ballard 的代码转储生成的。它坏了:当您检索句柄名称时,它偶尔会锁定。此代码不包含针对该问题的任何解决方法,并且 .NET 留下了几个选项: Thread.Abort 不能再中止当前在本机方法中的线程。

于 2013-08-08T16:17:04.123 回答