Suppose I just started the following programs in the background:
START /B CMD /C tomcat.exe
START /B CMD /C tomcat.exe
START /B CMD /C tomcat.exe
and I want to kill the second one. Because they have the same image name, I can't use taskkill
to kill them using tomcat.exe
or I'll kill more than I want.
What I want is to get the process ID of each when they're kicked off.
My question is: Is there a way to get the process ID of a console program I've just started in the background?
Here's a utility batch function that'll let you spawn a process and have its PID set to a variable. Copypaste this into the bottom of your script, after the final exit /b
or goto :EOF
so it can only be executed by call
. It looks complicated (and truth be told it is perhaps a little more complicated than the current situation requires), but it ought to handle backslashes and quoted arguments if you should ever need to recycle it for future projects.
:spawn command args
:: sets %PID% on completion
setlocal
set "PID="
set "return="
set "args=%*"
set "args=%args:\=\\%"
for /f "tokens=2 delims==;" %%I in (
'wmic process call create "%args:"=\"%" ^| find "ProcessId"'
) do set "return=%%I"
endlocal & set "PID=%return: =%"
goto :EOF
If you wmic process call create "ping localhost"
from a console, you'll see how this works. Unlike start /b
, using wmic process call create
to run a new asynchronous process will output the PID of the process as it's started.
Call the function above like this:
call :spawn tomcat.exe
set "instance1=%PID%"
call :spawn tomcat.exe
set "instance2=%PID%"
call :spawn tomcat.exe
set "instance3=%PID%"
:: kill the 2nd one:
taskkill /PID "%instance2%"