将我的开发环境从.Net 3.5切换到.Net 4.0后,下面的代码无法正常工作。我认为Marshal.GetLastWin32Error()的实现已经改变。
它使用.Net 3.5返回32但使用.Net 4.0则返回0.
如何解决此问题?有什么建议吗?
private StarterFile(string path, FileMode mode, FileAccess access, FileShare share, out bool isLocked)
{
isLocked = false;
m_Path = path;
m_Mode = mode;
m_Access = access;
m_Share = share;
try
{
m_Stream = new FileStream(path, mode, access, share);
m_Handle = m_Stream.SafeFileHandle;
}
catch (IOException)
{
int error = Marshal.GetLastWin32Error();
if (!HandleFileIoError(error, "File locked") && error == ERROR_SHARING_VIOLATION)
{
isLocked = true;
}
else
throw;
}
}
答案 0 :(得分:1)
FileStream没有改变,它仍然使用Marshal.GetLastWin32Error()本身来生成相应的异常。
可能已经改变的是位于FileStream代码和catch块之间的 mountain 代码。如果没有让错误代码改变,它们都无法调整winapi函数。
它是可修复的,IOException对象实际上存储了原始的winapi错误代码。将它从异常对象中删除有点尴尬,不幸的是,Exception.HResult是受保护的属性。但是有了后门,你可以用Marshal.GetHRForException()来解决它。您只需要处理已转换为COM错误代码的winapi错误代码,通过向该值添加0x80070000来完成。所以让它看起来像这样:
catch (IOException ex) {
var hr = (uint)Marshal.GetHRForException(ex);
if (hr == 0x80070000 + ERROR_SHARING_VIOLATION) {
// Report sharing violation
//...
}
}