In my Windows API wrapper ATL dll, I have exposed GetLastError
to COM for Windows API error handling.
It is implemented as below:
STDMETHODIMP CWinAPI::WinAPI_GetLastError(int *Result) {
*Result = (int)GetLastError();
return S_OK;
}
When I use it from VBScript like:
Dim WINAPI: Set WINAPI = WScript.CreateObject("WinAPIWrapperLib.WINAPI")
WINAPI.WinAPI_ShellExecute NULL, "", "NonExistentFile.exe", "", "", 1
WScript.Echo CStr(WINAPI.WinAPI_GetLastError)
This must generate the ERROR_FILE_NOT_FOUND
error, but when I call this windows API function from my wrapper dll via VBScript, it always returns ERROR_SUCCESS
.
But when I add following lines to my implementation for WinAPI_ShellExecute
like this:
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);
It correctly generates the error ERROR_FILE_NOT_FOUND
.
I like to know what goes wrong with GetLastError
.
Thanks in Advance.
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.
The problem is: you could not guarantee, that GetLastError
is called immediately after ShellExecute
. There is much going on between that calls - COM marshalling, VBScript calls, etc that most certainly affects thread last error flag. In fact you should not use GetLastError
in the VBScript altogether:
Visual Basic: Applications should call err.LastDllError instead of GetLastError.