2017-07-17 68 views
0

在我的Windows API封装器ATL DLL中,我公开了用于Windows API错误处理的COM组件GetLastErrorWinAPI - GetLastError在通过COM ATL DLL调用时总是返回0

据如下实施:

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错误,但是当我打电话从这个Windows API函数我封装DLL通过VBScript,它总是返回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出了什么问题。

在此先感谢。通过调用线程执行

回答

2

Remarks

函数调用 SetLastError函数设置此值。当函数的返回值指示这样的调用 将返回有用的数据时,应立即调用GetLastError函数 。这是因为一些函数在成功时调用 SetLastError,并清除由最近失败的函数设置的错误代码 。

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

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

+0

谢谢,但AutoIt也有这些功能实现。当我像上面那样使用AutoIt时,使用'Dllcall'调用WinAPI函数,然后通过单独的'Dllcall'得到最后一个错误,它正确地返回最后一个错误。为什么? – GTAVLover

+2

在每个API方法调用之后,它很可能会在内部缓存错误代码。 – Ari0nhh

+0

谢谢,我也会这样做,并通知你会发生什么。 – GTAVLover