为什么 Marshal.GetLastWin32Error 在调用 CallNtPowerInformation 后总是 returns 0?

Why Marshal.GetLastWin32Error after calling CallNtPowerInformation always returns 0?

我正在尝试使用 CallNtPowerInformation 获取 SystemBatteryState。我将 SetLastError 属性设置为 true,但 Marshal.GetLastWin32Error() 总是 returns 0,即使 CallNtPowerInformation 编辑的状态代码 return 不等于 0 .

我期望 GetLastWin32Error return 非零值的代码示例(我为 outputBuffer 分配的内存比需要的少):

var outputBufferLength = Marshal.SizeOf(typeof(SYSTEM_BATTERY_STATE)) - 1;
var outputBuffer = Marshal.AllocHGlobal(outputBufferLength);

var statusCode = CallNtPowerInformation(
    POWER_INFORMATION_LEVEL.SystemBatteryState,
    IntPtr.Zero,
    0,
    outputBuffer,
    (uint)outputBufferLength
);

var errorCode = Marshal.GetLastWin32Error();
Console.WriteLine("Win32 error code: " + errorCode);

我的CallNtPowerInformation:

[DllImport("powrprof.dll", SetLastError = true, ExactSpelling = true,
            CallingConvention = CallingConvention.Cdecl)]
private static extern uint CallNtPowerInformation(
    [In] POWER_INFORMATION_LEVEL informationLevel,
    [In] IntPtr inputBuffer,
    [In] uint inputBufferLength,
    [Out] IntPtr outputBuffer,
    [In] uint outputBufferLength
);

CallNtPowerInformationreturns代码3221225507(STATUS_BUFFER_TOO_SMALL),但是GetLastWin32Errorreturns 0.应该是return一些错误?或者我做错了什么?

P.S。也许只有来自 CallNtPowerInformation 的状态码就足够了,但为什么我们还需要 SetLastError = true

GetLastWin32Error 仅适用于文档中说它们设置了最后一个错误值的方法。 CallNtPowerInformationnot one of those。这个方法直接returns一个错误码,所以最后一个错误码不会被更新。在不使用最后一个错误值的方法声明中使用 SetLastError = true 是无用的并且没有任何效果(除了最终从先前失败的系统调用返回错误代码)。

对于更新 GetLastError 返回值的函数,文档明确说明了类似“使用 GetLastError 获取更多信息”的内容。