How can I kill child process using taskkill in a batch script? - windows

I'm capturing the PID in a variable which I kill later
IF NOT "%SERVICE_PID%" == 0 taskkill /pid %SERVICE_PID% /t /f
though everytime I do this in a batch file it makes my computer restart because it kills some system process
the service pid should be a user defined service launched from cmd
I dont understand why it keeps making my machine croak.
When I run "taskkill /pid %SERVICE_PID% /t /f" on the command line it works fine! =/
help!
Setting SERVICE_PID
FOR /F "tokens=4 delims= " %%A IN ('sc queryex myservice ^|FIND "PID"')
DO SET SERVICE_PID=%%A

I found that using this will get the proper PID:
for /f "tokens=1,2,3,4 delims=/ " %%a in ('sc queryex ServiceName ^|FIND "PID"') do set PID=%%c
taskkill /pid %PID% /t /f
Then it works like a charm.

Try removing /f option, it forces to terminate a process, so system processes might get terminated forcefully without notification.
I am suspecting you are trying to kill some system processes in the batch script, in the sense that in your list of PIDs there might be some system process IDs as well.
Thanks

Make sure you have enabled delayed expansion. See the HELP SET for an explanation.
Insert this line
SETLOCAL ENABLEDELAYEDEXPANSION
as the first line of your batch file.
and use !SERVICE_PID! instead of %SERVICE_PID% to get the environment variable.

taskkill /fi "IMAGENAME eq idsm.exe" /fi "CPUTIME gt 00:30:00"
Image Name PID Session Name Session# Mem Usage
========================= ======== ================ =========== ============
idsm.exe 4556 Console 0 38,328 K
I got the this result, in the same command line how to kill this process, its should run automatically, means how to use this PID for killing

I found this the most reliable
net stop SERVICE_NAME
timeout /t 10
for /f "tokens=1,2,3,4 delims=/ " %%a in ('sc queryex SERVICE_NAME ^|FIND "PID"') do set PID=%%c
if not %PID% == 0 taskkill /pid %PID% /f
timeout /t 10
net start SERVICE_NAME
The timeout is arbitrary.
The first timeout gives service a chance to stop itself properly for some extra amount of time.
The second timeout allows the operating system to react, otherwise you may end up with
The service is starting or stopping. Please try again later. and service will not restart.
I am checking if service is not stopped by if not %PID% == 0 and force killing it if necessary. The /t flag was unnecessary in my case.

Related

How to kill same name processes by differing them by their parameter? in BATCH / .bat

Henlo smarter folks.
While having fun with automating some workflows [im doing this in batch (/ vba)], btw this means if you think its better / easier to perform this in vba hit me, i faced the problem of using taskkill for multiple processes of the same name.
First i tried to circumvent this by using their pids's, but i figured that this wont work because it changes everytime a process restarts, at least the ones i look for do.
In short:
When ive got two or more processes of the same name with parameters like
example.exe -test abcd and
example.exe -testing;
How to kill only the first one?
In long ... :
For example, if i would do:
taskkill /f /im example.exe this would crash or bsod the machine etc, or do;
taskkill /PID example_pid this would prompt an error not found or maybe even kill the wrong process
The full batch looks like this:
test_autokill.bat
:start
timeout 5
taskkill /f /im example1.exe
taskkill /f /im example2.exe
taskkill /f /im *and so on*
goto start
Additionally i guessed that i would have to use tasklist first to output processes including their parameters, but searching to do so failed completely.
Also i am not sure about what i would have to do next especially because i wasnt able to perform if+else (i think it usually said 'dont know what else is') conditions with tasklist previously.
Thanks for your knowledge
EDIT 1
I was pointed to a related Topic which wanted to do the "opposide" of. Tho i tried it without the "not" modidier.
All tries (below) replied the same error Message:
ERROR:
Description = The request is invalid.
My tries (in AdminCLI):
wmic Path win32_process Where "CommandLine Like 'C:\Windows\System32\svchost.exe -k NetworkService'" Call Terminate
wmic Path win32_process Where "CommandLine Like 'C:\Windows\System32\svchost.exe -k NetworkService'" Delete
wmic Path win32_process Where "CommandLine Like 'C:\Windows\System32\svchost.exe -k NetworkService' and name='svchost.exe'" Call Terminate
wmic Path win32_process Where "CommandLine Like 'C:\Windows\System32\svchost.exe -k NetworkService' and name='svchost.exe'" Delete
The original ones had a typo btw, scv instead of svc.
With a batch file, you can try like this way if you want to kill the first PID, you just remove the echo before the Taskkill command in this example :
#echo off
Set "WMIC_CMD=WMIC Process Where "CommandLine Like '%%-k NetworkService'" get Handle /Value"
SetLocal EnableDelayedExpansion
#for /f "tokens=1* delims==" %%I in ('%WMIC_CMD%') do (
#for /F "delims=" %%K in ("%%J") do (
Set /A Count+=1
set "Handle[!Count!]=%%K"
)
)
#for /L %%i in (1,1,%Count%) do (
echo %%i - !Handle[%%i]!
)
pause
REM IF You want to kill the first one
ECHO Taskkill /F /PID !Handle[1]!
pause
exit /b

unable to find .bat pid for killing

I am unable to call a bat process within another bat.
This is the situation.
I have a n1.bat that basically contains:
TITLE "n1.bat"
...
...
start /b /MIN "n2.bat"
...
The n2.bat contains:
TITLE "n2.bat"
...
...
start someother.bat
start another.bat
exit
Now I use a third bat (n3.bat) that must kill everything.
TITLE "n3.bat"
...
TASKKILL /F /T /PID n1_PID
...
exit 0
Unfortunately when n3.bat ends a window called n1.bat - n2.bat remains active (the echo output belongs to n2.bat).
I tried to kill it in some ways:
1- Tried to get the process pid from tasklist -> there is no process called n2.bat or similar
TASKLIST /V /NH>Tasks.txt
FOR /F "tokens=2 delims= " %%n2_pid IN ('FINDSTR n2.bat Tasks.txt') DO SET PID=%%n2_pid
TASKKILL /PID %n2_pid%
2- Trying to use TASKKILL /F /FI "WINDOWTITLE eq n2.bat" -> no process found
I tried the previous solutions also starting n2.bat with
start /min "n2.bat" (so without /b)
with no success.
The only way I manage to kill it is to calling
TASKKILL /F /IM cmd.exe
that I really would like to avoid since it obviously kills all opened cmd.
Any ideas to retrieve the guilty pid?

timeout or close when process is finished

I have a X.exe program that takes about 2-6 hours to finish. Exact time is unknown, but I'd like to implement a threshold of 6.5 or 7 hours. If this program does not return any value by this amount of time, it will be killed. How do I implement this using batch *.bat files?
Here is what I had so far: a timer bat1.bat and an actual bat2.bat.
bat1.bat:
start cmd /C bat2.bat & timeout /t 25200 & taskkill /im X.exe /f
bat2.bat:
cd blah
bat1.bat
The problem with this approach is that only after 25200 seconds (or 7 hours) the timer will be stopped, and it won't be terminated before that limit. How do I tell the computer that if the program X.exe is finished then don't wait anymore?
Any help is appreciated!
I think this is a much simpler solution:
rem Start the process that will kill the X.exe program after 7 hours
start "WaitingToKill" cmd /C timeout /t 25200 ^& taskkill /im X.exe /f
rem Run the X.exe program and wait for it to terminate
X.exe
rem Kill the killer process and terminate
taskkill /fi "WINDOWTITLE eq WaitingToKill" /f
In this method there is not any additional code running at same time; just the waiting state of timeout command.
EDIT: Some explanations added
Note that both the "WaitingToKill" cmd.exe process with the timeout command and the X.exe program are running in parallel. If the timeout command ends after 7 hours, the taskkill /im X.exe /f command is executed, the X.exe program is killed and both cmd.exe processes ends.
If the X.exe program ends before the 7 hours, the Batch file execute the next line as usual. This line is taskkill /fi "WINDOWTITLE eq WaitingToKill" /f, so the window with the timeout command is killed and both cmd.exe processes ends.
thanks to #Squashman i was able to build a script on my own. seem to work fine
#echo off
setlocal enableextensions enabledelayedexpansion
set /a "checktime=60"
set /a "elapsedtime=0"
set /a "killtime=150"
set XProg=X.exe
start cmd /C runTest.bat
timeout /t 10
:while1
echo Go to WHILE loop.
echo elapsedtime = %elapsedtime%
echo killtime = %killtime%
set /a "timeleft = %killtime% - %elapsedtime%"
echo timeleft = %timeleft%
if /i %timeleft% geq 0 (
tasklist /fi "imagename eq %XProg%" 2>NUL | find /i /n "%XProg%">NUL
if "%ERRORLEVEL%"=="0" (
echo %XProg% is still running...
) else (
echo %XProg% is finished before timer.
)
set /a "elapsedtime = elapsedtime + checktime"
timeout /t %checktime%
goto :while1
) else (
taskkill /im %XProg% /f
echo %XProg% is terminated.
)
lessons learned:
1. hard to compare numeric variables in batch (compare diff with 0 instead)
2. terminated first time elaspedtime > killtime (might be a bit longer than killtime depending how often it checks)
I've tried various solutions but in the end this is really cumbersome in batch.
If you are willing to use an external tool the simplest way is
"C:\Program Files\Git\usr\bin\timeout.exe" 5 .\test.exe
It properly returns the exit code of the test process, also works if you spawn multiple test processes simultaneously and does not pop up windows all the time.

PID lookup to recall and kill task

I'd like to create the below two separate lines of cmd script into a bat file. The PID changes so I'm having a hard time figuring out how to set this service PID to be dynamic.
Any help would be welcomed thank you!!
sc queryex DWDesktopService
taskkill /f /pid ####
You just need to scrape the PID value out of the sc output. It is awkward in cmd scripting. Change the service name to yours. When you are satisfied that the correct PID will be killed, remove the echo from the TASKKILL line.
FOR /F "usebackq delims=: tokens=1,2" %%a IN (`sc queryex "BITS" ^| FIND /I " PID "`) DO (
SET "PID=%%b"
)
echo TASKKILL /F /PID %PID%

How to fetch the pid and kill it using batch file?

i have to find a processid for a specific jar file and kill it using the same batch file.
C:\Users\k9>ps -ef|grep java
10892 5648 0 Mar 08 con 0:02 "C:\Program Files\Java\jdk1.7.0_51\bin\java" com.mkwebappserver.MainClass -app CATMkWebAppServerConsole\apps_list.html -autobui
13060 7828 0 09:42:28 con 49:05 java -Djsse.enableSNIExtension=false -Djava.util.logging.config.file=..\config\log.properties -classpath "../extlib/*";..\extlib\mysql-connector-
here i want to find pid of config\log.properties file and kill it using the batch file.
This is how I "find" and kill Adobe Acrobat
::Close acrobat and any opened PDF
taskkill /im acrobat.exe /t /f
timeout 2
/im for imagename, or program you're targeting
/t terminates the specified process and any child process which were started by it
/f Forcefully terminate the process
The most flexible way to detect a pid by its command line (where your jar should be included) is with wmic. To process the wmic result and assign it to a variable you'll need FOR /F :
#echo off
for /f "useback tokens=* delims=" %%# in (
`wmic process where "CommandLine like '%%my_jar.jar%%' and not CommandLine like '%%wmic%%' " get ProcessId /Format:Value`
) do (
for /f "tokens=* delims=" %%a in ("%%#") do set "%%a"
)
echo %processId%
echo taskkill /pid %processId% /f
Where you should change '%%my_jar.jar%%' with your jar name.To kill the process you'll have to delete the echo word in the last line. It is echoed in order to check if the correct process id is handled.
For more info:
WMIC
FOR /F
WQL
TASKKILL

Resources