0

在我的 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

提前致谢。

4

1 回答 1

2

评论

调用线程执行的函数通过调用 SetLastError 函数设置此值。当函数的返回值表明这样的调用将返回有用的数据时,您应该立即调用 GetLastError 函数。这是因为某些函数在成功时调用 SetLastError 时使用零,从而消除了最近失败函数设置的错误代码。

问题是:你不能保证,那GetLastError是在ShellExecute. 这些调用之间发生了很多事情 - COM 编组、VBScript 调用等,这些调用肯定会影响线程最后一个错误标志。事实上,您不应该GetLastError完全在 VBScript 中使用:

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

于 2017-07-17T03:59:49.200 回答