I frequently call ShellExecute from a native C++/Win32 application to execute any shell item selected by the end-user from the GUI. Items are either executable files/scripts or links (.lnk). In some conditions that remain obscure to me, the following function sometimes returns 8
(SE_ERR_OOM
error; only very briefly documented). As a result, the item is not executed. What could possibly cause this error?
int doExecute(LPCTSTR file, LPCTSTR args, LPCTSTR workDir)
{
assert(file && *file);
HRESULT hRes = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
assert(hRes == S_OK || hRes == S_FALSE);
int code = (int)ShellExecute(NULL, NULL, file, args, workDir, SW_SHOWNORMAL);
doLog("ShellExecute returned: %d, %u", code, GetLastError()); // EDIT
CoUninitialize();
return code;
}
The context:
CoInitializeEx
have been blindly chosen after MSDN recommendation (see ShellExecute documentation), not because of a personal choiceObservations about the bug so far:
ShellExecute
always returned 0
.lnk
file, but not always the same fileProcess Explorer
(sysinternals.com) running on the machine does not show any peak of use of memorydoExecute
200 times in a row. All processes were spawned without error.After quite a long run of tests, the bug never occurred anymore after I applied some changes to the code, following advises from @DavidHeffernan and @RossRidge. While I can't really consider this as a definitive answer per se since I still don't know what happened exactly under the hood, I haven't been able to reproduce the bug so far.
Modifications applied:
ShellExecute
call by ShellExecuteEx
.CoInitializeEx
once for all for every new thread, without its CoUninitialize
counter-part. But kept the following nested CoInitializeEx
-CoUninitialize
pairs.Edit: In case someone needs it, just to confirm the problem didn't occur anymore, even after several months of tests, having these modifications applied.