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?
-
1@sarnold The problem is that Win32 is ... Win32. Some programs (like write) will *detach* from the parent process, while other programs (like notepad) do not. – Nov 18 '11 at 04:39
-
@pst: I thought you had to specifically use `start` to get the detachment... Oh wow. That's _horrible_. – sarnold Nov 18 '11 at 04:41
-
@sarnold Oops: notepad doesn't detach, write does. It's something relating to the write program, not necessarily Win32, although many UI programs (not meant to be called from a shell) seem to work like this. I am fairly certain `CreateProcess` is related though. – Nov 18 '11 at 04:42
-
@Apoc I would include a time-line explanation of what goes on, with a sample script with echos between the process to show detachment that occurs. Without the detaching the processes would run sequentially. – Nov 18 '11 at 04:45
8 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

- 34,977
- 11
- 70
- 85
-
2This is much simpler than a complete batch and works perfectly. Note that you will need to add the *title* argument if using quotes for your program name. See `help start` for more info. – Vincent Robert Jan 10 '13 at 10:55
-
Actually, why do you need `start /w` at all? I myself believed it's needed to use `start /w` to block batch file until GUI (as opposite to a console) application finishes. But testing it now, I see that batch files actually wait even for GUI applications. I have posted corresponding question: [Why GUI application blocks a batch file?](http://stackoverflow.com/questions/19381082/why-gui-application-blocks-a-batch-file) – Martin Prikryl Oct 15 '13 at 18:24
-
11This solution is good only when the batch file is also starting the process and not checking for an existing process. – orad Nov 03 '13 at 03:01
-
3This doesn't work if you want to start two or more processes at the same time and wait for all of them to complete. That's why Mitch Buz Stringer's answer is more desirable IMO. – Damien Jan 15 '16 at 06:21
-
1And it doesn't work if the started program detaches from its calling process (see comments on question). – Bowi May 10 '19 at 13:10
-
2what if you're starting a copy command, how do you exit the 2nd command prompt? – Rod Feb 04 '20 at 18:43
-
I have experienced the problems Bowi and Rod mentioned. Is there any solution to that? – damdafayton Sep 06 '22 at 07:58
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.

- 19,796
- 7
- 64
- 73
-
1TASKLIST doesnt receive arguments this way. how can i do it using tasklist? – Uri Abramson May 01 '13 at 11:52
-
14It looks like `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"`. – aphoria May 01 '13 at 13:14
-
4
-
3@DavidHeffernan `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. – aphoria Apr 16 '14 at 13:07
-
20This also works if the batch file didn't start the process, which is handy sometimes. – Blorgbeard May 14 '14 at 10:30
-
A downvote a for correct and accepted answer...and without leaving a comment? – aphoria Jun 24 '14 at 12:10
-
3I have a windows service deployment script that stops a service, then deploys the files, but the .exe hasn't always completely exited after the net stop call finishes, and the files are locked. This approach is exactly what I needed to ensure the service has actually stopped before copying the files. Thanks. – dhochee Jan 16 '15 at 22:45
-
1I am using your little script snippet very successfully to monitor the shutdown of a VmWare virtual machine running on top of Windows 7. Since pslist and sleep were not available on this system, I used the following replacements thanks to aphoria: instead of pslist, use: tasklist | find /i "vmware-vmx.exe" and instead of sleep, use timeout /t – Kevin P. May 10 '15 at 03:15
-
Dear downvoter, could you at least tell me what you don't like about this answer? – aphoria Feb 13 '16 at 13:28
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

- 399
- 3
- 5
-
7This is not an "updated" version of my answer. It is a copy of my answer that just replaces `PSLIST` and `PSEXEC` with `TASKKILL` and `TASKLIST`, which I listed as alternatives in my answer. – aphoria Jan 15 '16 at 14:04
-
1Thank you. The best answer if the process happens to spawn additional processes as the /wait solution wont work. Simply use similar code for the additional processes to solve such situations. – Robert Sep 16 '16 at 23:45
-
2@aphoria: I think he posted this because psexec and pslist are not part of (some?) Windows, they are sysinternals programs. Also, if they are run for the first time, they pop up a dialog box to agree to license terms. Not ideal to use, unless you control the target computer and can pre-install these tools. And it is definitely "updated": you need to know how to use `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. – Abel Oct 28 '17 at 23:42
-
2@Abel I listed `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. – aphoria Oct 30 '17 at 00:39
-
6@aphoria, Exactly, and your answer is good. This one helps people that cannot rely on those tools being there, it's quite different, and gives you credit and helps me and others. Didn't know about that switch, thanks. – Abel Oct 30 '17 at 00:43
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.

- 808
- 1
- 9
- 18
-
5
-
1Ah I see. But then is there any difference between calling "My.exe" directly, versus "START /B My.exe"? It seems like the same thing. – Gabe Halsmer Nov 27 '13 at 16:30
call process1
call process2
in this case the process2 will not begin until process1 have finished.

- 569
- 7
- 15
-
You should read the question (and the comments) more carefully. In the first comment it's explained why `CALL` isn't a general solution – jeb Jan 30 '18 at 12:41
This 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

- 151
- 1
- 5
-
fwiw: on my windows 10 laptop this worked when I saved aboe to a .bat file and called it from command prompt (it failed when I cut and pasted to command window) – spioter Sep 25 '20 at 16:13
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

- 21
- 2
'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

- 11
- 1
-
This worked great for me. I used it to run pyinstaller. I needed to be sure that the pyinstaller process had finished generating its /dist/... folder output before copying some config files to the same output folder. If I didn't wait for the end of the pyinstaller process, the output folder would disappear for some reason. – Ephie Nov 19 '19 at 08:12