@@ -200,59 +200,43 @@ int Portable::system(const QCString &command,const QCString &args,bool commandHa
200200 }
201201 else
202202 {
203- // Because ShellExecuteEx can delegate execution to Shell extensions
204- // (data sources, context menu handlers, verb implementations) that
205- // are activated using Component Object Model (COM), COM should be
206- // initialized before ShellExecuteEx is called. Some Shell extensions
207- // require the COM single-threaded apartment (STA) type.
208- // For that case COM is initialized as follows
209- CoInitializeEx (nullptr , COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
210-
211- uint16_t *commandw = nullptr ;
212- recodeUtf8StringToW ( commandCorrectedPath, &commandw );
213- uint16_t *argsw = nullptr ;
214- recodeUtf8StringToW ( args, &argsw );
215-
216- // gswin32 is a GUI api which will pop up a window and run
217- // asynchronously. To prevent both, we use ShellExecuteEx and
218- // WaitForSingleObject (thanks to Robert Golias for the code)
219-
220- SHELLEXECUTEINFOW sInfo = {
221- sizeof (SHELLEXECUTEINFOW), /* structure size */
222- SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI, /* tell us the process
223- * handle so we can wait till it's done |
224- * do not display msg box if error
225- */
226- nullptr , /* window handle */
227- nullptr , /* action to perform: open */
228- (LPCWSTR)commandw, /* file to execute */
229- (LPCWSTR)argsw, /* argument list */
230- nullptr , /* use current working dir */
231- SW_HIDE, /* minimize on start-up */
232- nullptr , /* application instance handle */
233- nullptr , /* ignored: id list */
234- nullptr , /* ignored: class name */
235- nullptr , /* ignored: key class */
236- 0 , /* ignored: hot key */
237- nullptr , /* ignored: icon */
238- nullptr /* resulting application handle */
239- };
240-
241- if (!ShellExecuteExW (&sInfo ))
203+ uint16_t * fullCmdW = nullptr ;
204+ recodeUtf8StringToW (fullCmd, &fullCmdW);
205+
206+ STARTUPINFOW sStartupInfo ;
207+ std::memset (&sStartupInfo , 0 , sizeof (sStartupInfo ));
208+ sStartupInfo .cb = sizeof (sStartupInfo );
209+ sStartupInfo .dwFlags |= STARTF_USESHOWWINDOW;
210+ sStartupInfo .wShowWindow = SW_HIDE;
211+
212+ PROCESS_INFORMATION sProcessInfo ;
213+ std::memset (&sProcessInfo , 0 , sizeof (sProcessInfo ));
214+
215+ if (!CreateProcessW (
216+ nullptr , // No module name (use command line)
217+ reinterpret_cast <wchar_t *>(fullCmdW), // Command line, can be mutated by CreateProcessW
218+ nullptr , // Process handle not inheritable
219+ nullptr , // Thread handle not inheritable
220+ FALSE , // Set handle inheritance to FALSE
221+ CREATE_NO_WINDOW,
222+ nullptr , // Use parent's environment block
223+ nullptr , // Use parent's starting directory
224+ &sStartupInfo ,
225+ &sProcessInfo
226+ ))
242227 {
243- delete[] commandw;
244- delete[] argsw;
228+ delete[] fullCmdW;
245229 return -1 ;
246230 }
247- else if (sInfo .hProcess ) /* executable was launched, wait for it to finish */
231+ else if (sProcessInfo .hProcess ) /* executable was launched, wait for it to finish */
248232 {
249- WaitForSingleObject (sInfo .hProcess ,INFINITE);
233+ WaitForSingleObject (sProcessInfo .hProcess ,INFINITE);
250234 /* get process exit code */
251235 DWORD exitCode;
252- bool retval = GetExitCodeProcess (sInfo .hProcess ,&exitCode);
253- CloseHandle (sInfo .hProcess );
254- delete[] commandw ;
255- delete[] argsw ;
236+ bool retval = GetExitCodeProcess (sProcessInfo .hProcess ,&exitCode);
237+ CloseHandle (sProcessInfo .hProcess );
238+ CloseHandle ( sProcessInfo . hThread ) ;
239+ delete[] fullCmdW ;
256240 if (!retval) return -1 ;
257241 return exitCode;
258242 }
0 commit comments