[PATCH 04/18] CMD: Attempt launch even if fails to locate program

Jason Edmeades us at edmeades.me.uk
Thu Mar 29 16:21:02 CDT 2007


Internal programs will not be found on the path and hence cannot
be run (a good example is xcopy). FindExecutable and SHGetFileInfo
will not report on them either, so try a CreateProcess regardless,
and assume worst case - ie a console app, and wait for it to end.
---
 programs/cmd/wcmdmain.c |   47 +++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index d49e25f..c21e15c 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -815,6 +815,8 @@ void WCMD_run_program (char *command, int called) {
   BOOL  launched = FALSE;
   BOOL  status;
   DWORD len;
+  STARTUPINFO st;
+  PROCESS_INFORMATION pe;
 
 
   WCMD_parse (command, quals, param1, param2);	/* Quick way to get the filename */
@@ -916,8 +918,6 @@ void WCMD_run_program (char *command, int called) {
 
     /* Once found, launch it */
     if (found) {
-      STARTUPINFO st;
-      PROCESS_INFORMATION pe;
       SHFILEINFO psfi;
       DWORD console;
       HINSTANCE hinst;
@@ -977,13 +977,44 @@ void WCMD_run_program (char *command, int called) {
     }
   }
 
-  /* Not found anywhere - give up */
-  SetLastError(ERROR_FILE_NOT_FOUND);
-  WCMD_print_error ();
+  /* Internal programs wont be picked up by this, so try one final
+     createprocess and wait for it to complete.
+     Note: Ideally we could tell between a console app (wait) and a
+     windows app, but the API's for it fail in this case           */
+  ZeroMemory (&st, sizeof(STARTUPINFO));
+  st.cb = sizeof(STARTUPINFO);
+  init_msvcrt_io_block(&st);
+
+  /* Launch the process and assume CUI so wait on it to complete */
+  status = CreateProcess (NULL, command, NULL, NULL, TRUE,
+                          0, NULL, NULL, &st, &pe);
+
+  if ((opt_c || opt_k) && !opt_s && !status &&
+       GetLastError()==ERROR_FILE_NOT_FOUND && command[0]=='\"') {
+    /* strip first and last quote characters and try again */
+    WCMD_opt_s_strip_quotes(command);
+    opt_s=1;
+    WCMD_run_program(command, called);
+    return;
+  }
+
+  /* If it still fails, give up */
+  if (!status) {
+    SetLastError(ERROR_FILE_NOT_FOUND);
+    WCMD_print_error ();
+    /* If a command fails to launch, it sets errorlevel 9009 - which
+       does not seem to have any associated constant definition     */
+    errorlevel = 9009;
+    return;
+  }
+
+  /* Wait for it to end */
+  WaitForSingleObject (pe.hProcess, INFINITE);
+  GetExitCodeProcess (pe.hProcess, &errorlevel);
+  if (errorlevel == STILL_ACTIVE) errorlevel = 0;
+  CloseHandle(pe.hProcess);
+  CloseHandle(pe.hThread);
 
-  /* If a command fails to launch, it sets errorlevel 9009 - which
-     does not seem to have any associated constant definition     */
-  errorlevel = 9009;
   return;
 
 }
-- 
1.5.0




More information about the wine-patches mailing list