WinAPI - 当通过COM ATL DLL调用时,GetLastError始终返回0

时间:2017-07-17 03:24:24

标签: c++ dll vbscript 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函数时,它总是返回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出了什么问题。

先谢谢。

1 个答案:

答案 0 :(得分:2)

  

Remarks

     

调用线程执行的函数通过调用来设置该值   SetLastError函数。您应该调用GetLastError函数   当函数的返回值指示这样的调用时立即   将返回有用的数据。那是因为有些函数会调用   SetLastError成功时为零,消除错误代码   由最近失败的功能设置。

问题是:您无法保证在GetLastError之后立即调用ShellExecute。这些调用之间有很多事情 - COM编组,VBScript调用等,这肯定会影响线程的最后一个错误标志。实际上你不应该在VBScript中完全使用GetLastError

  

Visual Basic:应用程序应调用err.LastDllError而不是   GetLastError函数。