2017-07-17 63 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