Wait for multiple applications run asynchronously from batch file to finish

后端 未结 6 1438
再見小時候
再見小時候 2020-12-13 21:15

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

相关标签:
6条回答
  • 2020-12-13 21:49

    You are starting several instances of the same app.exe?

    • start them all
    • loop tasklist |find "app.exe" until %errorlevel% is 1
    • continue with your script
    0 讨论(0)
  • 2020-12-13 21:51

    Basically, you're doing it right using the START command becuase it is inteded for what you need now.

    In addition, I would suggest you to refering to this great answer: https://stackoverflow.com/a/1449192/952310

    UPDATE:

    For waiting each program to finish, use the /W switch, look:

    start /w app.exe param1
    start /w app.exe param2
    
    0 讨论(0)
  • 2020-12-13 21:52

    Adapting on @dbenham answer, here's how i made it to work inside a for and for unlimited number of processes:

    setlocal enabledelayedexpansion
    for %%a in (*.*) do start "" 9>"%temp%/wait!random!.lock" /b /low "myprogram.exe" -program_parameters
    
    :wait
    ping /n 2 ::1 > nul
    echo waiting processes to finish...
    2>nul del "%temp%\wait*.lock" > nul
    if exist "%temp%\wait*.lock" goto :wait
    
    ... more commands ...
    

    Here %random% don't work, cause it's expanded when for is called, therefore making all numbers the same. So I enabledelayedexpansion and use !random!.

    On the loop I try to delete all files. 2>nul will make sure any error won't show on screen. It will only go through when all can be deleted (if exist).

    0 讨论(0)
  • 2020-12-13 21:55

    Powershell has more sophisticated ways to do it without wait loops. You can wrap or call your scripts with powershell and even implement your preferred managed solutions for doing it exactly as you do it in C#.

    0 讨论(0)
  • 2020-12-13 21:56

    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
    
    0 讨论(0)
  • 2020-12-13 22:10

    In a separate batch file asynchBatch.bat put:

    start app.exe param1
    start app.exe param2
    

    Then in caller batch file write:

    call asynchBatch.bat
    other executions
    ...
    

    The other executions will start only after both app.exe param1 and app.exe param2 finish.

    0 讨论(0)
提交回复
热议问题