When I want to close the following two (fictional...) applications using taskkill...
...I would use taskkill /FI "WINDOWTITLE eq Hello*".
But how about these two:
taskkill /FI "WINDOWTITLE eq * wine" gives me FEHLER: Der Suchfilter wurde nicht erkannt., which can be translated as ERROR: The search filter could not be recognized.
So, how can I filter with a wildcard at the beginning?
The wildcard at the beginning does not work. You would need to incorporate findstr using a bit of initiative.
for /f "tokens=2 delims=," %%a in ('tasklist /fi "imagename eq notepad.exe" /v /fo:csv /nh ^| findstr /r "wine"') do taskkill /pid %%a
So we search for imagenames with wine in the name. Use /fo to csv format, /nh for no header, then search for the string "wine" in imagename, then kill by process ID if found.
To not be imagename specific do:
for /f "tokens=2 delims=," %%a in ('tasklist /v /fo:csv /nh ^| findstr /r "wine"') do taskkill /pid %%a
Edit
As for the concern in killing incorrect tasks:
#echo off
set "images=notepad.exe,calc.exe,winword.exe,excel.exe"
for %%i in (%images%) do (
for /f "tokens=2 delims=," %%a in ('tasklist /fi "imagename eq %%i" /v /fo:csv /nh ^| findstr /r "wine"') do taskkill /pid %%a
)
Just add a list of possible image names that would contain the title, it will only loop these as per below and not touch the other processes/tasks:
tasklist /fi "imagename eq notepad.exe"
tasklist /fi "imagename eq calc.exe"
tasklist /fi "imagename eq winword.exe"
tasklist /fi "imagename eq excel.exe"
Related
I have this batch code and its working perfectly well, BUT:
every line take ~60 seconds to execute and I'm wondering, if I could do this faster...
Also the if Statements.. I want to check, if every Window is closed, and if so, I want to execute something. But if at least one window is still open, then it should check it again.
:loop
for /f %%i in ('tasklist /v /fi "WINDOWTITLE eq %server1%" /FO Table') do set #1=%%i
for /f %%i in ('tasklist /v /fi "WINDOWTITLE eq %server2%" /FO Table') do set #2=%%i
for /f %%i in ('tasklist /v /fi "WINDOWTITLE eq %server3%" /FO Table') do set #3=%%i
for /f %%i in ('tasklist /v /fi "WINDOWTITLE eq %server4%" /FO Table') do set #4=%%i
for /f %%i in ('tasklist /v /fi "WINDOWTITLE eq %server5%" /FO Table') do set #5=%%i
for /f %%i in ('tasklist /v /fi "WINDOWTITLE eq %server6%" /FO Table') do set #6=%%i
if not %#1%==cmd.exe (
if not %#2%==cmd.exe (
if not %#3%==cmd.exe (
if not %#4%==cmd.exe (
if not %#5%==cmd.exe (
if not %#6%==cmd.exe (
goto backup
)
)
)
)
)
) else (
echo back to loop
goto openWindow
)
Let me suggest a slightly different approach. Instead of all those if statements, you can just loop whenever one of the tasks exist:
:wait
timeout 1 >nul
for %%a in (%server1% %server2% %server3% %server4% %server5% %server6%) do (
tasklist /nh /fi "windowtitle eq %%a" |find " " >nul && goto :wait
)
echo all closed.
or
setlocal enabledelayedexpansion
:wait
timeout 1 >nul
for /l %%a in (1,1,6) do (
tasklist /nh /fi "windowtitle eq !server%%a!" |find " " >nul && goto :wait
)
echo all closed.
Note: find " " looks for two consecutive spaces, not a TAB)
If you choose your window titles wisely, you don't even need a for loop:
:wait
timeout 1 >nul
tasklist /nh /fi "windowtitle eq MySubWindow*" |find " " >nul && goto :wait
echo all closed.
where the window titles all start with a fixed string (MySubWindow here), like MySubWindow-1, MySubWindow-2 etc. (yes, tasklist is able to use a wildcard - but only at the end of the string). This is basically "if any window exists with a title that starts with MySubWindow then loop"
little optimization of Stephan answer.
This execute faster.
:wait
timeout 1 >nul
for %%a in (%server1% %server2% %server3% %server4% %server5% %server6%) do (
if not defined v%%a tasklist /nh /fi "windowtitle eq %%a" |find " " >nul && goto :wait
set v%%a=done
)
echo all closed.
You have not explained how your 6 Batch files are "open", but if they are open via START command, then there is a much simpler way to do the same:
(
start call batch1.bat
start call batch2.bat
start call batch3.bat
start call batch4.bat
start call batch5.bat
start call batch6.bat
) | pause
echo All 6 Batch files are closed
The previous code run the 6 Batch files in parallel and then the control flow is stopped at the pause command. When all the 6 Batch files terminates, this program continue.
Note that there is not any Batch code that check if the procesess ends; this is done automatically by the Operating System. In this way, the wait state of this program does not waste any CPU time. For a further explanation, see this answer
Without being able to test this, perhaps it would be quicker to run just one tasklist command per loop:
#Echo Off
SetLocal EnableExtensions
:Loop
For /F Tokens^=17^ Delims^=^" %%G In (
'%SystemRoot%\System32\tasklist.exe /Fi "ImageName Eq cmd.exe" /Fo CSV /NH /V 2^>NUL'
) Do Set /P "=%%G" 0<NUL | %SystemRoot%\System32\findstr.exe /I ^
"\<%server1%\> \<%server2%\> \<%server3%\> \<%server4%\> \<%server5%\> \<%server6%\>" 1>NUL && GoTo Loop
:Backup
The findstr.exe options may need to be adjusted depending upon the content of those variables.
I'm trying to log the memory usage of browsers for exemple for Chrome / Firefox etc.
For Firefox I can simply use this little command line:
tasklist /fo csv /fi "imagename eq firefox.exe" > DumpResults.csv
And this will nicely result with one proces and its usage. But when applying this train of thoughts to Chrome you'll get around 4 processes even when you did a clean launch of Chrome. Is there any way to sum the results?
Sorry for the stupid question but it's my first attempt to create a bat file.
An alternative…
#Echo Off
Set "sum=0"
For /F "Tokens=6-7 Delims=., " %%a In (
'TaskList /NH /FI "ImageName Eq chrome.exe"') Do Set/A sum+=%%a%%b
Set sum
Pause
…prevents using two loops
#echo off
set sum=0
for /f "tokens=5 delims=," %%x in ('tasklist /fo csv /nh /fi "imagename eq chrome.exe"') do (
for /f "tokens=1-4 delims=.K " %%a in (%%x) do set /a sum+=%%a%%b%%c%%d
)
echo Sum Chrome = %sum%
Maybe you have to adapt the delimiters to your local settings. Output on my computer is like:
C:\Users> tasklist /fo csv /nh /fi "imagename eq chrome.exe"
"chrome.exe","7744","Console","1","86.388 K"
"chrome.exe","7784","Console","1","1.312 K"
"chrome.exe","7920","Console","1","50.188 K"
...
I want to write a simple batch file to kill a process that contains certain text in the window title. Right now I have:
taskkill /fi "Windowtitle eq XXXX*" /im cmd.exe
And that works, except what I want to do is use the wildcard both at the beginning AND end of the title. So something like:
taskkill /fi "Windowtitle eq \*X*" /im cmd.exe
But I tried this and it does not work. Is there something I'm missing or is this not possible?
No, wildcards are not allowed at the start of the filter.
for /f "tokens=2 delims=," %%a in ('
tasklist /fi "imagename eq cmd.exe" /v /fo:csv /nh
^| findstr /r /c:".*X[^,]*$"
') do taskkill /pid %%a
This will retrieve the list of tasks, in csv and verbose format (that will include window title as the last field in the output).
The list is filtered by findstr with a regular expression that will search the indicated text (the X) in the last field.
If any line matches the filter, the for will tokenize it, retrieving the second field (the PID) that will be used in taskkill to end the process.
In the special case you have started the command window from a batch file yourself, you can specify the window title using the command
START MyWindowTitle c:/MyProcess.exe
That way it is easy to kill the process again using just
taskkill /fi "WindowTitle eq MyWindowTitle"
A little more elaborate, but you can use:
for /f "tokens=2 delims== " %%A in ('tasklist /nh /fi "imagename eq cmd.exe" /fi "windowtitle eq MyWindowTi*"') do set "PID=%%A"
taskkill /F /T /PID !PID!
I can get a proper output wuth the below command in the command prompt,
tasklist /fi "imagename ne siebde*" /fi "imagename eq sieb*" /svc | find "gtwyns".
But if i want to use this condition in batch files i have to do this with the below command.
for /f "tokens=2 delims= " %%a in ('tasklist /fi "imagename ne siebde*" /fi "imagename eq sieb*" /svc ^| find "gtwyns")
I need to understand the function of ^ character and how does it work actually?
I also wanna know does it open a new cmd when wi use a pipe in batch script?
Read FOR /F: loop command against the results of another command syntax:
FOR /F ["options"] %%parameter IN ('command_to_process') DO command
…
command_to_process : The output of the 'command_to_process' is passed
into the FOR parameter.
… The command_to_process can be almost any internal or external
command.
Almost any internal or external command (but the only command).
Now, read redirection syntax:
commandA | commandB Pipe the output from commandA into
commandB
For instance, in wrong for /F "delims=" %%a in ('dir /B | sort /R') do echo %%~awith unescaped | pipe:
commandA evaluates to for /F "delims=" %%a in ('dir /B and
commandB evaluates to sort /R') do echo %%~a although separate dir /B | sort /R is right command.
Hence, we need to escape (all) &, |, <, > redirection characters and (sometimes) " double quotes as follows (both ways are equivalent parsing dir /B "*.vbs" 2>NUL | sort /R command):
for /F "delims=" %%a in (' dir /B "*.vbs" 2^>NUL ^| sort /R ') do echo %%~a
for /F "delims=" %%a in ('"dir /B ""*.vbs"" 2>NUL | sort /R"') do echo %%~a
Therefore, next two loops should work the same way:
for /f "tokens=2 delims= " %%a in ('
tasklist /fi "imagename ne siebde*" /fi "imagename eq sieb*" /svc ^| find "gtwyns"
') do echo set pid_ns=%%a
and
for /f "tokens=2 delims= " %%a in ('
"tasklist /fi ""imagename ne siebde*"" /fi ""imagename eq sieb*"" /svc | find ""gtwyns"""
') do echo set pid_ns=%%a
I'm making a batch that checks whether the process is active and if it is closed it ... the point is that when the process has spaces in the name it is not found.
Set "EXE=Process name.exe">nul 2>&1
FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF %%x == %EXE% Taskkill /F /IM "%EXE%" >nul 2>&1
This should handle the spaces in the code, depending on what the first tasklist prints:
Set "EXE=Process name.exe"
FOR /F "delims=" %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF /i "%%x" == "%EXE%" Taskkill /F /IM "%EXE%" >nul 2>&1
This is another way of doing it:
Set "EXE=Process name.exe"
tasklist|find /i "%EXE%" >nul && Taskkill /F /IM "%EXE%" >nul 2>&1
and this is functionally equivalent: it will only kill the task if it exists.
Set "EXE=Process name.exe"
Taskkill /F /IM "%EXE%" >nul 2>&1
wmic process where name="Process name.exe" get Name,ProcessId
?
Try, putting quotes around your process name like
Set EXE="Process name.exe" >nul 2>&1