@@ -200,59 +200,43 @@ int Portable::system(const QCString &command,const QCString &args,bool commandHa
200
200
}
201
201
else
202
202
{
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
+ ))
242
227
{
243
- delete[] commandw;
244
- delete[] argsw;
228
+ delete[] fullCmdW;
245
229
return -1 ;
246
230
}
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 */
248
232
{
249
- WaitForSingleObject (sInfo .hProcess ,INFINITE);
233
+ WaitForSingleObject (sProcessInfo .hProcess ,INFINITE);
250
234
/* get process exit code */
251
235
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 ;
256
240
if (!retval) return -1 ;
257
241
return exitCode;
258
242
}
0 commit comments