C# GetLastWin32Error()实现更改

C# GetLastWin32Error()实现更改,c#,.net-4.0,.net-3.5,C#,.net 4.0,.net 3.5,在我将开发环境从.NET3.5切换到.NET4.0之后,下面的代码无法正常工作。我认为Marshal.GetLastWin32Error()的实现已经更改 在.NET3.5中返回32,但在.NET4.0中返回0 我如何解决这个问题?有什么建议吗 private StarterFile(string path, FileMode mode, FileAccess access, FileShare share, out bool isLocked) { isLocked =

在我将开发环境从.NET3.5切换到.NET4.0之后,下面的代码无法正常工作。我认为Marshal.GetLastWin32Error()的实现已经更改

在.NET3.5中返回32,但在.NET4.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;
        }
    }

FileStream没有更改,它仍然使用Marshal.GetLastWin32Error()本身来生成相应的异常

可能已经改变的是位于FileStream代码和catch块之间的堆积如山的代码。所有这些都不能在不更改错误代码的情况下pinvoke winapi函数

它是可修复的,IOException对象实际上存储原始winapi错误代码。从exception对象exception.HResult中取出它有点尴尬,不幸的是,exception.HResult是一个受保护的属性。但是有了后门,您可以通过Marshal.GetHRForException()将其释放出来。您只需将0x80070000添加到值中,即可处理已转换为COM错误代码的winapi错误代码。所以让它看起来像这样:

        catch (IOException ex) {
            var hr = (uint)Marshal.GetHRForException(ex);
            if (hr == 0x80070000 + ERROR_SHARING_VIOLATION) {
                // Report sharing violation
                //...
            }
        }

FileStream没有更改,它仍然使用Marshal.GetLastWin32Error()本身来生成相应的异常

可能已经改变的是位于FileStream代码和catch块之间的堆积如山的代码。所有这些都不能在不更改错误代码的情况下pinvoke winapi函数

它是可修复的,IOException对象实际上存储原始winapi错误代码。从exception对象exception.HResult中取出它有点尴尬,不幸的是,exception.HResult是一个受保护的属性。但是有了后门,您可以通过Marshal.GetHRForException()将其释放出来。您只需将0x80070000添加到值中,即可处理已转换为COM错误代码的winapi错误代码。所以让它看起来像这样:

        catch (IOException ex) {
            var hr = (uint)Marshal.GetHRForException(ex);
            if (hr == 0x80070000 + ERROR_SHARING_VIOLATION) {
                // Report sharing violation
                //...
            }
        }

对IO函数调用失败后GetLastWin32Error有意义,不属于IO函数的文档约定的一部分,因此可能会在不另行通知的情况下进行更改。对IO函数调用失败后GetLastWin32Error有意义不属于IO函数的文档约定的一部分,GetHRForException()方法设置当前线程的IErrorInfo。这可能导致我的申请结果不一致。这完全是胡说八道。IErrorInfo只对COM客户端重要。如果您重新抛出异常,那么它仍然会被COM互操作层设置。如果这是太多的FUD,那么使用反射来挖掘属性值。你的意思是,这样使用它没有异议吗?GetHRForException()方法设置当前线程的IErrorInfo。这可能导致我的申请结果不一致。这完全是胡说八道。IErrorInfo只对COM客户端重要。如果您重新抛出异常,那么它仍然会被COM互操作层设置。如果这是太多的FUD,那么使用反射来挖掘属性值。那么你的意思是,没有人反对这样使用它?