WinAPI - GetLastError 在通过 COM ATL DLL 调用时总是 returns 0
WinAPI - GetLastError always returns 0 when called via a COM ATL DLL
在我的 Windows API 包装器 ATL dll 中,我已将 GetLastError
暴露给 COM 以进行 Windows API 错误处理。
具体实现如下:
STDMETHODIMP CWinAPI::WinAPI_GetLastError(int *Result) {
*Result = (int)GetLastError();
return S_OK;
}
当我从 VBScript 使用它时,例如:
Dim WINAPI: Set WINAPI = WScript.CreateObject("WinAPIWrapperLib.WINAPI")
WINAPI.WinAPI_ShellExecute NULL, "", "NonExistentFile.exe", "", "", 1
WScript.Echo CStr(WINAPI.WinAPI_GetLastError)
这一定会产生 ERROR_FILE_NOT_FOUND
错误,但是当我通过 VBScript 从我的包装器 dll 中调用这个 windows API 函数时,它总是 returns ERROR_SUCCESS
.
但是当我像这样在 WinAPI_ShellExecute
的实现中添加以下行时:
DWORD ErrorMessageID = ::GetLastError();
wchar_t ErrorID[1024];
swprintf_s(ErrorID, 1024, L"%d", ErrorMessageID);
MessageBox(nullptr, (LPCWSTR)&ErrorID, L"GetLastError", MB_OK | MB_ICONERROR | MB_DEFBUTTON1);
它正确地生成错误 ERROR_FILE_NOT_FOUND
。
我想知道 GetLastError
出了什么问题。
提前致谢。
Functions executed by the calling thread set this value by calling the
SetLastError function. You should call the GetLastError function
immediately when a function's return value indicates that such a call
will return useful data. That is because some functions call
SetLastError with a zero when they succeed, wiping out the error code
set by the most recently failed function.
问题是:您无法保证 GetLastError
在 ShellExecute
之后立即被调用。在这些调用之间发生了很多事情——COM 编组、VBScript 调用等肯定会影响线程最后一个错误标志。事实上,您不应该在 VBScript 中完全使用 GetLastError
:
Visual Basic: Applications should call err.LastDllError instead of
GetLastError.
在我的 Windows API 包装器 ATL dll 中,我已将 GetLastError
暴露给 COM 以进行 Windows API 错误处理。
具体实现如下:
STDMETHODIMP CWinAPI::WinAPI_GetLastError(int *Result) {
*Result = (int)GetLastError();
return S_OK;
}
当我从 VBScript 使用它时,例如:
Dim WINAPI: Set WINAPI = WScript.CreateObject("WinAPIWrapperLib.WINAPI")
WINAPI.WinAPI_ShellExecute NULL, "", "NonExistentFile.exe", "", "", 1
WScript.Echo CStr(WINAPI.WinAPI_GetLastError)
这一定会产生 ERROR_FILE_NOT_FOUND
错误,但是当我通过 VBScript 从我的包装器 dll 中调用这个 windows API 函数时,它总是 returns ERROR_SUCCESS
.
但是当我像这样在 WinAPI_ShellExecute
的实现中添加以下行时:
DWORD ErrorMessageID = ::GetLastError();
wchar_t ErrorID[1024];
swprintf_s(ErrorID, 1024, L"%d", ErrorMessageID);
MessageBox(nullptr, (LPCWSTR)&ErrorID, L"GetLastError", MB_OK | MB_ICONERROR | MB_DEFBUTTON1);
它正确地生成错误 ERROR_FILE_NOT_FOUND
。
我想知道 GetLastError
出了什么问题。
提前致谢。
Functions executed by the calling thread set this value by calling the SetLastError function. You should call the GetLastError function immediately when a function's return value indicates that such a call will return useful data. That is because some functions call SetLastError with a zero when they succeed, wiping out the error code set by the most recently failed function.
问题是:您无法保证 GetLastError
在 ShellExecute
之后立即被调用。在这些调用之间发生了很多事情——COM 编组、VBScript 调用等肯定会影响线程最后一个错误标志。事实上,您不应该在 VBScript 中完全使用 GetLastError
:
Visual Basic: Applications should call err.LastDllError instead of GetLastError.