C# 如何获取最后一个错误(WSAGetLastError)?

C# 如何获取最后一个错误(WSAGetLastError)?,c#,.net,winapi,error-handling,pinvoke,C#,.net,Winapi,Error Handling,Pinvoke,如何从WinAPI调用WSAGetLastError(),以获得有效的文本错误?从托管代码调用该函数没有多大意义。这在非托管代码中是有意义的,因为您知道调用的最后一个Win32函数的确切位置,所以您知道必须是哪个函数设置了最后一个错误。在托管代码中,您不知道调用了哪些函数 您可能可以使用p/Invoke来调用函数;这对你没有任何好处。您想实现什么?WSAGetLastError只是Win32GetLastError函数的包装 如果使用p/Invoke执行操作,则可以将SetLastError参数

如何从WinAPI调用
WSAGetLastError()
,以获得有效的文本错误?

从托管代码调用该函数没有多大意义。这在非托管代码中是有意义的,因为您知道调用的最后一个Win32函数的确切位置,所以您知道必须是哪个函数设置了最后一个错误。在托管代码中,您不知道调用了哪些函数


您可能可以使用p/Invoke来调用函数;这对你没有任何好处。您想实现什么?

WSAGetLastError
只是Win32
GetLastError
函数的包装

如果使用p/Invoke执行操作,则可以将
SetLastError
参数用于
DllImport
属性。它告诉.NET导入的函数将调用
SetLastError()
,并且应该收集该值

如果导入的函数失败,可以使用
Marshal.GetLastWin32Error()
获取最后一个错误。或者,您可以只
抛出新的Win32Exception()
,它会自动使用此值

如果您没有使用p/Invoke进行操作,那么您就不走运了:无法保证最后一个错误值会被保留足够长的时间,以使其通过.NET代码的多层返回。事实上,我会链接到Adam Nathan:

还有,上面说:

您永远不应该PInvoke访问GetLastError。改为调用Marshal.GetLastWin32Error


这就是我在web上看到的将GetLastError放入C#exception机制的方法,以及如何再次将其取出的方法

try
{
    // some p/invoke call that is going to fail with a windows error ...
    mHndActivatedDevice = MyNameSpace.Interop.Device.Device.ActivateDevice(
         "Drivers\\BuiltIn\\SomeDriverName", IntPtr.Zero, 0, IntPtr.Zero);
}
catch(System.ComponentModel.Win32Exception exc) // as suggested by John Saunders
{
    // you can get the last error like this:
    int lastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
    Console.WriteLine("error:" + lastError.ToString());

    // but it is also inside the exception, you can get it like this
    Console.WriteLine(exc.NativeErrorCode.ToString());

    Console.WriteLine(exc.ToString());
}

其中ActivateDevice是这样定义的:

-1:代码应该捕获Win32Exception,而不是Exception。否则,可能会捕获其他异常类型,然后Win32Exception的案例将失败。
try
{
    // some p/invoke call that is going to fail with a windows error ...
    mHndActivatedDevice = MyNameSpace.Interop.Device.Device.ActivateDevice(
         "Drivers\\BuiltIn\\SomeDriverName", IntPtr.Zero, 0, IntPtr.Zero);
}
catch(System.ComponentModel.Win32Exception exc) // as suggested by John Saunders
{
    // you can get the last error like this:
    int lastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
    Console.WriteLine("error:" + lastError.ToString());

    // but it is also inside the exception, you can get it like this
    Console.WriteLine(exc.NativeErrorCode.ToString());

    Console.WriteLine(exc.ToString());
}