How to wait for a process to terminate before executing another process in a batch file? Let's say I have a process notepad.exe that I need to kill before executing wordpad.exe. Then, when wordpad.exe is terminated, I need to launch notepad.exe again. How do I do that?
9 Answers
Use start /w programname to wait for the end of programname
START /W notepad ECHO Back from notepad START /W wordpad ECHO Back from wordpad START /W notepad 7 Comments
help start for more info.Try something like this...
@ECHO OFF PSKILL NOTEPAD START "" "C:\Program Files\Windows NT\Accessories\wordpad.exe" :LOOP PSLIST wordpad >nul 2>&1 IF ERRORLEVEL 1 ( GOTO CONTINUE ) ELSE ( ECHO Wordpad is still running TIMEOUT /T 5 GOTO LOOP ) :CONTINUE NOTEPAD I used PSLIST and PSEXEC, but you could also use TASKKILL and TASKLIST. The >nul 2>&1 is just there to hide all the output from PSLIST. The SLEEP 5 line is not required, but is just there to restrict how often you check if WordPad is still running.
9 Comments
TASKLIST doesn't set the ERRORLEVE. You can pipe the output of TASKLIST through FIND as a workaround. Something like this, TASKLIST | FIND /I "wordpad".start /wait like nature intended.START /WAIT is fine if you want everything to stop until the process completes. My simple example doesn't really show it, but you can use this technique to kick-off a process and then do some other stuff, but not go on after a certain point until that first process has ended.This is an updated version of aphoria's Answer.
I Replaced PSLIST and PSEXEC with TASKKILL and TASKLIST`. As they seem to work better, I couldn't get PSLIST to run in Windows 7.
Also replaced Sleep with TIMEOUT.
This Was everything i needed to get the script running well, and all the additions was provided by the great guys who posted the comments.
Also if there is a delay before the .exe starts it might be worth inserting a Timeout before the :loop.
@ECHO OFF TASKKILL NOTEPAD START "" "C:\Program Files\Windows NT\Accessories\wordpad.exe" :LOOP tasklist | find /i "WORDPAD" >nul 2>&1 IF ERRORLEVEL 1 ( GOTO CONTINUE ) ELSE ( ECHO Wordpad is still running Timeout /T 5 /Nobreak GOTO LOOP ) :CONTINUE NOTEPAD 5 Comments
PSLIST and PSEXEC with TASKKILL and TASKLIST, which I listed as alternatives in my answer.find (or findstr) to make this work (pslist is easier in that respect). Though an edit of your answer with this version would have sufficed too, imo.TASKKILL and TASKLIST as alternatives in my answer before this answer was posted. Also, not that it matters for my answer, but the SysInternals utilities support a /accepteula switch.I liked the "START /W" answer, though for my situation I found something even more basic. My processes were console applications. And in my ignorance I thought I would need something special in BAT syntax to make sure that the 1st one completed before the 2nd one started. However BAT appears to make a distinction between console apps and windows apps, and it executes them a little differently. The OP shows that window apps will get launched as an asynchronous call from BAT. But for console apps, that are invoked synchronously, inside the same command window as the BAT itself is running in.
For me it was actually better not to use "START /W", because everything could run inside one command window. The annoying thing about "START /W" is that it will spawn a new command window to execute your console application in.
2 Comments
call process1 call process2 in this case the process2 will not begin until process1 have finished.
1 Comment
CALL isn't a general solutionThis works and is even simpler. If you remove ECHO-s, it will be even smaller:
REM REM DEMO - how to launch several processes in parallel, and wait until all of them finish. REM @ECHO OFF start "!The Title!" Echo Close me manually! start "!The Title!" Echo Close me manually! :waittofinish echo At least one process is still running... timeout /T 2 /nobreak >nul tasklist.exe /fi "WINDOWTITLE eq !The Title!" | find ":" >nul if errorlevel 1 goto waittofinish echo Finished! PAUSE 1 Comment
'start /w' does NOT work in all cases. The original solution works great. However, on some machines, it is wise to put a delay immediately after starting the executable. Otherwise, the task name may not appear in the task list yet, and the loop will not work as expected (someone pointed that out). The 2 delays can be combined and put at the top of the loop. Can also get rid of the 'else' just to shorten. Example of 2 programs running sequentially:
c:\prog1.exe :loop1 timeout /t 1 /nobreak >nul 2>&1 tasklist | find /i "prog1.exe" >nul 2>&1 if errorlevel 1 goto cont1 goto loop1 :cont1 c:\prog2.exe :loop2 timeout /t 1 /nobreak >nul 2>&1 tasklist | find /i "prog2.exe" >nul 2>&1 if errorlevel 1 goto cont2 goto loop2 :cont2 john refling
1 Comment
This is my adaptation johnrefling's. This work also in WindowsXP; in my case i start the same application at the end, because i want reopen it with different parametrs. My application is a WindowForm .NET
@echo off taskkill -im:MyApp.exe :loop1 tasklist | find /i "MyApp.exe" >nul 2>&1 if errorlevel 1 goto cont1 echo "Waiting termination of process..." :: timeout /t 1 /nobreak >nul 2>&1 ::this don't work in windows XP :: from: https://stackoverflow.com/questions/1672338/how-to-sleep-for-five-seconds-in-a-batch-file-cmd/33286113#33286113 typeperf "\System\Processor Queue Length" -si 1 -sc 1 >nul s goto loop1 :cont1 echo "Process terminated, start new application" START "<SYMBOLIC-TEXT-NAME>" "<full-path-of-MyApp2.exe>" "MyApp2-param1" "MyApp2-param2" pause
startto get the detachment... Oh wow. That's horrible.CreateProcessis related though.