2017-07-17 13 views
0

Windows APIラッパーATL dllでは、Windows APIエラー処理のCOMにGetLastErrorが公開されています。WinAPI - GetLastErrorは、COM ATL DLL経由で呼び出されたときに常に0を返します。

以下のように実装されます。私は私からこのWindows API関数を呼び出すとき

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のからそれを使用する場合

STDMETHODIMP CWinAPI::WinAPI_GetLastError(int *Result) { 

    *Result = (int)GetLastError(); 

    return S_OK; 
} 

ラッパー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を0で呼び出して、最後に失敗した関数によって設定されたエラーコード を消去する関数があるためです。

問題は:GetLastErrorShellExecuteの直後に呼び出されることを保証できないことです。 COMマーシャリング、VBScript呼び出しなど、その呼び出しの間には多くのことがあります。これは、スレッドの最後のエラーフラグに最も確実に影響します。実際には、あなたは完全にVBScriptでGetLastErrorを使用しないでください。

のVisual Basic:アプリケーションが代わりに のGetLastErrorのerr.LastDllErrorを呼び出す必要があります。

+0

ありがとうございますが、AutoItにはこれらの機能も実装されています。上記のようなAutoItを使用し、 'Dllcall'を使用してWinAPI関数を呼び出し、別の' Dllcall'で最後のエラーを取得すると、最後のエラーが正しく返されます。なぜですか? – GTAVLover

+2

ほとんどの場合、各APIメソッド呼び出し後に内部的にエラーコードがキャッシュされます。 – Ari0nhh

+0

ありがとう、私も同じことを行い、何が起こるかを通知します。 – GTAVLover

関連する問題