Skip to content

Replace ShellExecuteExW with simple CreateProcessW #11699 #11703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 6, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Replace ShellExecuteExW with simple CreateProcessW #11699
  • Loading branch information
Andreas Ringlstetter committed Aug 5, 2025
commit be192aacb2321c5da36d6ce0de4480fa97479938
78 changes: 31 additions & 47 deletions src/portable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,59 +200,43 @@ int Portable::system(const QCString &command,const QCString &args,bool commandHa
}
else
{
// Because ShellExecuteEx can delegate execution to Shell extensions
// (data sources, context menu handlers, verb implementations) that
// are activated using Component Object Model (COM), COM should be
// initialized before ShellExecuteEx is called. Some Shell extensions
// require the COM single-threaded apartment (STA) type.
// For that case COM is initialized as follows
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

uint16_t *commandw = nullptr;
recodeUtf8StringToW( commandCorrectedPath, &commandw );
uint16_t *argsw = nullptr;
recodeUtf8StringToW( args, &argsw );

// gswin32 is a GUI api which will pop up a window and run
// asynchronously. To prevent both, we use ShellExecuteEx and
// WaitForSingleObject (thanks to Robert Golias for the code)

SHELLEXECUTEINFOW sInfo = {
sizeof(SHELLEXECUTEINFOW), /* structure size */
SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI, /* tell us the process
* handle so we can wait till it's done |
* do not display msg box if error
*/
nullptr, /* window handle */
nullptr, /* action to perform: open */
(LPCWSTR)commandw, /* file to execute */
(LPCWSTR)argsw, /* argument list */
nullptr, /* use current working dir */
SW_HIDE, /* minimize on start-up */
nullptr, /* application instance handle */
nullptr, /* ignored: id list */
nullptr, /* ignored: class name */
nullptr, /* ignored: key class */
0, /* ignored: hot key */
nullptr, /* ignored: icon */
nullptr /* resulting application handle */
};

if (!ShellExecuteExW(&sInfo))
uint16_t* fullCmdW = nullptr;
recodeUtf8StringToW(fullCmd, &fullCmdW);

STARTUPINFOW sStartupInfo;
std::memset(&sStartupInfo, 0, sizeof(sStartupInfo));
sStartupInfo.cb = sizeof(sStartupInfo);
sStartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
sStartupInfo.wShowWindow = SW_HIDE;

PROCESS_INFORMATION sProcessInfo;
std::memset(&sProcessInfo, 0, sizeof(sProcessInfo));

if (!CreateProcessW(
nullptr, // No module name (use command line)
reinterpret_cast<wchar_t*>(fullCmdW), // Command line, can be mutated by CreateProcessW
nullptr, // Process handle not inheritable
nullptr, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
CREATE_NO_WINDOW,
nullptr, // Use parent's environment block
nullptr, // Use parent's starting directory
&sStartupInfo,
&sProcessInfo
))
{
delete[] commandw;
delete[] argsw;
delete[] fullCmdW;
return -1;
}
else if (sInfo.hProcess) /* executable was launched, wait for it to finish */
else if (sProcessInfo.hProcess) /* executable was launched, wait for it to finish */
{
WaitForSingleObject(sInfo.hProcess,INFINITE);
WaitForSingleObject(sProcessInfo.hProcess,INFINITE);
/* get process exit code */
DWORD exitCode;
bool retval = GetExitCodeProcess(sInfo.hProcess,&exitCode);
CloseHandle(sInfo.hProcess);
delete[] commandw;
delete[] argsw;
bool retval = GetExitCodeProcess(sProcessInfo.hProcess,&exitCode);
CloseHandle(sProcessInfo.hProcess);
CloseHandle(sProcessInfo.hThread);
delete[] fullCmdW;
if (!retval) return -1;
return exitCode;
}
Expand Down
Loading