GetLastWin32Error()实现更改

时间:2013-10-08 14:50:26

标签: c# .net-4.0 .net-3.5

将我的开发环境从.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;
        }
    }

1 个答案:

答案 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
                //...
            }
        }