WinAPI — GetLastError всегда возвращает 0 при вызове через библиотеку COM ATL

В моей оболочке 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 ошибка, но когда я вызываю эту функцию Windows API из моей библиотеки оболочки через 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,

Заранее спасибо.

0

Решение

замечания

Функции, выполняемые вызывающим потоком, устанавливают это значение, вызывая
Функция SetLastError. Вы должны вызвать функцию GetLastError
немедленно, когда возвращаемое значение функции указывает, что такой вызов
вернет полезные данные. Это потому, что некоторые функции вызывают
SetLastError с нулем, когда они успешны, стирая код ошибки
устанавливается последней ошибочной функцией.

Проблема в том, что вы не можете гарантировать, что GetLastError вызывается сразу после ShellExecute, Между этими вызовами происходит много событий — маршалинг COM, вызовы VBScript и т. Д., Что, несомненно, влияет на флаг последней ошибки потока. На самом деле вы не должны использовать GetLastError в VBScript вообще:

Visual Basic: приложения должны вызывать err.LastDllError вместо
GetLastError.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]