Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for multiple applications run asynchronously from batch file to finish

There is a simple Windows batch file that runs multiple instances of application:

start app.exe param1
start app.exe param2

Is there a way to run them asynchronously at the same time (which above does) and wait for them both to finish to perform other actions - something like C#

Task.WhenAll(tasksList.ToArray());
/* Process tasksList.Result */

?
/wait switch will not help here, some polling for if particular instance is still running maybe.

like image 462
Jaded Avatar asked Sep 12 '13 07:09

Jaded


People also ask

What is the wait command in a batch file?

You can use the timeout command: This utility accepts a timeout parameter to wait for the specified time period (in seconds) or until any key is pressed. It also accepts a parameter to ignore the key press. For example, to wait for 10 seconds: TIMEOUT /T 10.

What is batch Errorlevel?

Batch file error level: %ERRORLEVEL% is an environment variable that contains the last error level or return code in the batch file – that is, the last error code of the last command executed. Error levels may be checked by using the %ERRORLEVEL% variable as follows: IF %ERRORLEVEL% NEQ 0 ( DO_Something )

What does Colon do in batch?

By adding a colon in front of a word, such as LABEL, you create a category, more commonly known as a label. A label lets you skip to certain sections of a batch file such as the end of the batch file.


1 Answers

I suppose this question is slightly different than Waiting for parallel batch scripts in that this application is waiting for .exe processes to finish instead of batch scripts. But the solution is nearly identical.

You must instantiate some form of polling in your master batch script. You can effectively create a lock file via redirection. The lock file remains locked until the process terminates. Your batch script polls, checking if it can open all the lock files. Once it succeeds, it knows all the processes have ended.

The only significant difference in the solution below is that START launches the .exe directly instead of launching a batch through CMD /C. I also learned that (call ) is an extremely fast way to effectively perform a no-op that always succeeds. So I substitued (call ) in place of rem

@echo off
setlocal
set "lock=%temp%\wait%random%.lock"

:: Launch processes asynchronously, with stream 9 redirected to a lock file.
:: The lock file will remain locked until the script ends.
start "" 9>"%lock%1" notepad.exe
start "" 9>"%lock%2" notepad.exe

:Wait for both processes to finish (wait until lock files are no longer locked)
1>nul 2>nul ping /n 2 ::1
for %%N in (1 2) do (
  (call ) 9>"%lock%%%N" || goto :Wait
) 2>nul

::delete the lock files
del "%lock%*"

:: Finish up
echo Done - ready to continue processing

See Parallel execution of shell processes for a pretty sophisticated application of the lock technique that regulates the maximum number of parallel processes, with the ability to direct processes to specific CPUs or machines via PSEXEC. That answer also provides a fuller explanation of exactly how the lock file technique works.


EDIT

The wait loop can be modified so that it does not need to change as you add more processes:

:Wait for all processes to finish (wait until lock files are no longer locked)
1>nul 2>nul ping /n 2 ::1
for %%F in ("%lock%*") do (
  (call ) 9>"%%F" || goto :Wait
) 2>nul
like image 68
dbenham Avatar answered Oct 05 '22 01:10

dbenham