views:

547

answers:

2

Hi,

i want to do the following from a Windows batch script:

start proc1.exe

start proc2.exe

...

start procN.exe

<wait for all N processes to complete> <-- What do i put here?

So how do i wait for all spawned processes to complete?

TIA.

A: 

You could do this if you write .NET code or Win32 C/C++ code to start the processes, but there is no way to do it in a batch file. once you use start to make proc1.exe run async, there is no batch command that allows you to come back later and wait for it to complete.

But you can do this easily in one of the scripting languages designed for batch work, python, WSH, etc.

For example, heres a simple script using Windows Script Host. WSH is included in all versions of Windows since Windows 98. So this script should run anywhere.

This script starts 2 programs and waits for them both to finish. Save it as as start2.wsf. The just use it in your batch file start2.wsf "prog1.exe" "prog2.exe"

<package>
 <job id="Start 2 Procs">
  <runtime>
   <description>Start 2 programs and wait for them both to finish.
   </description>
   <unnamed
      name="program"
      helpstring="the program to run"
      many="false"
      required="2"
   />
   <example>
Example: Start2.wsf "cl -c foo.obj" "cl -c bar.obj"
   </example>
  </runtime>

  <script language="JScript">

   if (WScript.Arguments.length < 2)
   {
      WScript.Arguments.ShowUsage();
      WScript.Quit();
   }

   var proc1 = WScript.Arguments.Unnamed.Item(0);
   var proc2 = WScript.Arguments.Unnamed.Item(1);

   var Shell = WScript.CreateObject("WScript.Shell");
   var oProc1 = Shell.Exec(proc1);
   var oProc2 = Shell.Exec(proc2);

   while (oProc1.Status == 0 && oProc2.Status == 0)
   {
      WScript.Sleep(1000);
   }

  </script>
 </job>
</package>
John Knoeller
You are wrong. You can do in a .BAT. Either (1)invoke proc.exe without START or (2)use the `START /WAIT` command line parameter. See `HELP START`
PA
@PA: you misread what I wrote.
John Knoeller
@PA: Neither of your suggestions would allow the processes to run in parallel.
Jeremy Stein
@Jeremy: you are right, that was not the intention. The intention was to correctly state that you can invoke a program and wait for it to finish.
PA
@john: My comment was to some wording you wrote meaning a .BAT cannot wait for a process to finish. After the major edit of your answer, my comment has no sense any more.
PA
+2  A: 

This is ugly, but you could wrap each command in another batch file that runs the command and then signals that the command is complete. Your main batch file would call each of those batch files asynchronously and sit in a loop waiting for the signals.

For example:

main.bat

start cmd /c proc1.bat
start cmd /c proc2.bat
:wait
sleep 1
IF NOT EXIST proc1done GOTO wait
IF NOT EXIST proc2done GOTO wait
del proc1done
del proc2done
echo All processes are complete

proc1.bat

proc1.exe
echo Done > proc1done

The sleep command is available in Windows Server 2003 Resource Kit Tools. If you don't have that, you could use a ping on localhost just to slow down that tight loop.

Jeremy Stein
I would probably prefer having the main batch file create the files, and then have the proc files delete them. That way, you don't risk seeing a process as being done in case only some of the processes completed in the previous run. (You can get around that by deleting any existing files before running the start commands, but as far as I can tell, it should be slightly less code if you changed it around).
Michael Madsen
Good suggestion.
Jeremy Stein
Thanks. I guess this will do for now. I will have to a simple Win32 app that does the spawning for the long term.
zr