This is my code so far ive tested it and both programs open when .bat is run , What im after is the code to close program 2 when program 1 closes any help would be appriciated as i have no coding knowledge :(
#echo off
start "TestFolder" "C:\Program Files (x86)\testfolder\test1.exe" %1
start "Testfolder2" "C:\Program Files (x86)\testfolder2\test2.exe"
taskkill /f /im test2.exe
exit
You need to setup a FOR /F Loop to monitor the output of TaskList to check for the window title of the 2nd program (and you'll need to explicitly set the window title of that program to something unique to do that.)
Then you will need to use Taskkill to kill the other task.
#(SETLOCAL
echo off )
CALL :Main
( ENDLOCAL
EXIT /B )
:Main
start "TestFolder1" "C:\Program Files (x86)\testfolder\test1.exe" %1
start "Testfolder2" "C:\Program Files (x86)\testfolder2\test2.exe"
CALL :Loop
taskkill /f /im test2.exe
GOTO :EOF
:loop
SET /A "n=10"
TIMEOUT 10
tasklist /V /NH /FI "IMAGENAME eq test1.exe" | FIND /I "TestFolder1" &&(
GOTO :loop
)
GOTO :EOF
Related
I have a series of bat files that I want to run in parallel, for example:
start program1_1.bat
start program1_2.bat
start program1_3.bat
wait until program1 finished then
start program2_1.bat
start program2_2.bat
start program2_3.bat
wait until program2 finished then
...
So far, what I've tried is this function:
:waitForFinish
set counter=0
for /f %%i in ('tasklist /NH /FI "Imagename eq cmd.exe') do set /a counter=counter+1
if counter GTR 2 Goto waitForFinish
But it just launched the first 3 bat files and stop... How can I solve this problem?
Thanks,
EDIT: This is the content of program1_i.bat file:
program1.exe input_i.txt
It will run program1.exe for each input file. The same for program2_i.bat.
Your question is a little vague on the exact expected results.
I am however assuming that you want to do something like this.
start /wait program1_1.bat | start /wait program1_2.bat | start /wait program1_3.bat
start /wait program2_1.bat | start /wait program2_2.bat | start /wait program2_3.bat
The single pipe separators let's us launch the first three commands in parallel and only start the next three commands once the first three has all completed, simply because the next 3 commands are in the next batch line the use of start /wait
* Update *
The solution provided here works nicely to achieve parallel running of subprograms without needing user entry (pause) or a fixed length Timeout between program groups.
Combined with the original answer:
#echo off
:controller
Call :launcher "program1_1.bat" "program1_2.bat" "program1_3.bat"
Call :launcher "program2_1.bat" "program2_2.bat" "program2_3.bat"
pause
EXIT
:launcher
For %%a in (%*) Do (
Start "+++batch+++" "%%~a"
)
:loop
timeout /t 1 >nul
tasklist /fi "windowtitle eq +++batch+++*" |find "cmd.exe" >nul && goto :loop
GOTO :EOF
Original Answer:
This is a simple way to ensure each group of programs is finished before the next. The fault in the tasklist method is that if there's other cmd.exe processes running, the If condition may not be true when expected, causing the script to hang.
The start /wait option is not ideal, as you intend on running multiple programs simultaneously - and if the subprogram you wait on finishes before the other subs, you're back to square 1.
#echo off
:controller
Call :launcher "program1_1.bat" "program1_2.bat" "program1_3.bat"
Call :launcher "program2_1.bat" "program2_2.bat" "program2_3.bat"
pause
EXIT
:launcher
For %%a in (%*) Do (
Start "" "%%~a"
)
pause
GOTO :EOF
Ok, here is what worked for me:
#echo off
setlocal enableextensions enabledelayedexpansion
call :InitDos
start program1_1.bat
start program1_2.bat
start program1_3.bat
call :waitForFinish
start program2_1.bat
start program2_2.bat
start program2_3.bat
call :waitForFinish
Goto:eof
: waitForFinish
set /a counter=0
for /f %%i in ('tasklist /NH /FI "Imagename eq cmd.exe"') do (
set /a counter+=1
)
if !counter! GTR !init_count! Goto waitForFinish
goto :eof
: InitDos
set /a init_count=0
for /f %%i in ('tasklist /NH /FI "Imagename eq cmd.exe"') do (
set /a init_count+=1
)
goto :eof
Try /WAIT switch on start command. I guess if you wrap bats into script called with wait switch, it could work.
I got this script form stackoverflow and its working for me . and because i can't comment there im asking my question in new post.
This script check if exe is running in tasklist:
#echo off
SETLOCAL EnableExtensions
set EXE=notepad.exe
FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF %%x == %EXE% goto ProcessFound
goto ProcessNotFound
:ProcessFound
echo %EXE% is running
goto END
:ProcessNotFound
echo %EXE% is not running
goto END
:END
echo Finished!
The question is :
How can I check multiple process is running on tasklist?
for example exe1 and exe2
thanks in advance
From your comments; if all you want to do is run a third executable if neither of two other executables are running then here is a single line complete batch file example for you:
#TaskList/NH /FI "Status Eq Running"|FindStr/IC:"first.exe" /C:"second.exe">Nul||Start "" "X:\PathTo\third.exe"
Note:Do not change anything other than the names first, second and X:\PathTo\third; all double quotes, ", are necessary!
I've organised your code a bit differently so it's easier to follow and has more functionality. Note: This means it will be slower if you have lots of processes. If you wish to only see if it exists, I'd recommend using findstr.
I've added REM (batch-file equivalent for comments) explaining what each section does.
#echo off
REM Create variable's for exe's and their counter
set exe_1=notepad.exe
set exe_2=explorer.exe
set exe_3=chrome.exe
set "count_1=0"
set "count_2=0"
set "count_3=0"
REM Store all tasklist findings in a temp file
>tasklist.temp (
tasklist /NH /FI "IMAGENAME eq %exe_1%"
tasklist /NH /FI "IMAGENAME eq %exe_2%"
tasklist /NH /FI "IMAGENAME eq %exe_3%"
)
REM Go through all finds and count for each task instance
for /f %%x in (tasklist.temp) do (
if "%%x" EQU "%exe_1%" set /a count_1+=1
if "%%x" EQU "%exe_2%" set /a count_2+=1
if "%%x" EQU "%exe_3%" set /a count_3+=1
)
REM Use variables to see instance count
Echo %exe_1%: %count_1%
Echo %exe_2%: %count_2%
Echo %exe_3%: %count_3%
REM Use GTR 0 to see if process exists
if %count_1% GTR 0 if %count_2% GTR 0 Echo Both notepad and explorer are open
REM Delete temp file once finished. (NB: Will still exist if your code crashes)
del tasklist.temp
Conditional if-statements
As requested from your comment:
if %count_1% GTR 0 if %count_2% GTR 0 (
Echo Both notepad and explorer are open
goto :finish
)
if %count_1% GTR 0 (
Echo Only notepad is open
goto :finish
)
if %count_2% GTR 0 (
Echo Only explorer is open
goto :finish
)
REM Not Finished means none are open
Echo Neither notepad nore explorer are open
:finish
Here is my solution, keeping a similar structure to that of your sample script. Modify the EXE variable to reference the IMAGENAMEs you're interested in checking.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET EXE=(notepad.exe wordpad.exe winword.exe thunderbird.exe outlook.exe greenshot.exe)
FOR %%i IN %EXE% DO (
TASKLIST /NH /FI "IMAGENAME EQ %%i" 2>NUL | FIND /I /N "%%i">NUL
IF !ERRORLEVEL! EQU 0 ( CALL :ProcessFound %%i ) ELSE ( CALL :ProcessNotFound %%i )
)
ECHO Finished^^!
EXIT /B 0
:ProcessFound
ECHO %1 is running
EXIT /B 0
:ProcessNotFound
ECHO %1 is not running
EXIT /B 1
If you want to start the program when the process is not found, insert START %1 after ECHO %1 is not running.
I'm trying to realize a batch file that checks if a program is running and if not launch it, and more if is it launched more than one time close all the duplicate instances.
this is the code I implemented using also some tips found here in stackoverflow:
:check
tasklist /fi "imagename eq notepad.exe" /nh |find /i /c "notepad.exe" > "%temp%\variable.txt" #here I count how many instances are running
set /p value=<"%temp%\variable.txt" #and save the value in the variable.txt file
##check and choose action
if %value% equ nul goto none
if %value% geq 2 goto more
if %value% equ 1 goto one
:more
for /f "tokens=2" %%x in ('tasklist ^| findstr notepad.exe') do set PIDTOKILL=%%x
taskkill /F /PID %PIDTOKILL%
goto check
:none
start notepad.exe
goto check
:one
timeout 10 > nul
goto check
But some strange behavior happens when I test it...
if only one instances is running all fine, but if I close notepad while the batch file is running the routine goes to the :more label apparently without any reason...what I'm doing wrong?
thanks for any help
stupid error ... this is the working code:
:check
timeout 10 > nul
tasklist /fi "imagename eq notepad.exe" /nh |find /i /c "notepad.exe" > "%temp%\variable.txt"
set /p value=<"%temp%\variable.txt"
if %value% equ 0 goto none
if %value% geq 2 goto more
if %value% equ 1 goto check
:more
for /f "tokens=2" %%x in ('tasklist ^| findstr notepad.exe') do set PIDTOKILL=%%x
taskkill /F /PID %PIDTOKILL%
goto check
:none
start notepad.exe
goto check
I'm having problems with the firefox Flashplayerplugin eating up too much ram and lagging my system when it's not in use. The only solution I found was killing the flashplayerplugin while using firefox, uninstalling, reinstalling or a fresh firefox install or new profile doesn't solve it; however, it's becoming very tedious having to check taskmanager all the time and kill it and the flashplayerplugin always seems to start on it's own.
The question I have is if it's possible to create a batch file to check if FlashPlugin_11_8_800_94.exe is running and kill it after a period of time (5-10 seconds) and continue running the batch file actively, in a loop, scanning if FlashPlugin_11_8_800_94.exe has started again, then kill it after 5 - 10 seconds, rinse and repeat?
Edit:
Found a batch file and modified it, but also seems to be missing some perimeters to actively search if it's running, even when it is not. It doesn't work either way though.
#echo off
:search
TASKLIST|FIND "FlashPlayerPlugin"
IF %ERRORLEVEL% = 0 THEN (GOTO found)
TIMEOUT /T 5
GOTO search
:found
taskkill /im FlashPlayerPlugin_11_8_800_94.exe
--
This batch file doesn't work either.
set tasklist=%windir%\System32\tasklist.exe
set taskkill=%windir%\System32\taskkill.exe
-------------------------------------------------------
:STOPPROC
set wasStopped=0
set procFound=0
set notFound_result=ERROR:
set procName=%1
for /f "usebackq" %%A in (`%taskkill% /IM %procName%`) do (
if NOT %%A==%notFound_result% (set procFound=1)
)
if %procFound%==0 (
echo The process was not running.
goto :EOF
)
set wasStopped=1
set ignore_result=INFO:
:CHECKDEAD
"%windir%\system32\timeout.exe" 3 /NOBREAK
for /f "usebackq" %%A in (`%tasklist% /nh /fi "imagename eq %procName%"`) do (
if not %%A==%ignore_result% (goto :CHECKDEAD)
)
goto :EOF
-------------------------------------------------------
:MAIN
call :STOPPROC FlashPlayerPlugin_11_8_800_94.exe
taskkill /im FlashPlugin_11_8_800_94* /f >nul 2>&1
For anyone who still might find it useful:
This is a small script that scans tasklist for processes containing processname once every 5 seconds. For example, if you put "notepad" for the processname, it will end processes like "notepad.exe" and "notepad++.exe". To use the script, copy and paste the following into notepad and save has "simple_pk.cmd". processname can have any characters except double quotes("), ampersands (&), or commas (,).
::Simple monitor and kill process
#echo off&prompt :&mode con cols=50 lines=10
set processname=flashplayerplugin
:loop
cls&echo Searching for %processname%...
for /f "tokens=1 delims=," %%a in ('tasklist /fo csv ^|FINDSTR /I /C:"%processname%"') do call :killprocess %%a
ping -n 6 127.0.0.1>NUL
goto :loop
:killprocess
echo. |set /p d=killing %*...
taskkill /f /im "%*">nul 2>&1
set err=%errorlevel%
set success=Success
if not %err%==0 set success=fail (err code: %err%)
if %err%==128 set success=fail (process not found)
echo %success%&goto :eof
This is a slightly different version of the same script. This will only end processes that match the whole name exactly:
::Simple monitor and kill process (exact name)
#echo off&prompt :&mode con cols=50 lines=10
set processname=FlashPlayerPlugin_11_8_800_94.exe
:loop
cls&echo Searching for %processname%...
for /f "tokens=1 delims=," %%a in ('tasklist /fo csv ^|FINDSTR /C:"%processname%"') do call :killprocess %%a
ping -n 6 127.0.0.1>NUL
goto :loop
:killprocess
set name=%*
set name=.,;%name:"=%;,.
echo %name%|FINDSTR /C:".,;%processname%;,.">nul || goto :eof
echo. |set /p d=killing %*...
taskkill /f /im "%*">nul 2>&1
set err=%errorlevel%
set success=Success
if not %err%==0 set success=fail (err code: %err%)
if %err%==128 set success=fail (process not found)
echo %success%&goto :eof
Your IF is not correct:
#echo off
:search
TASKLIST|FIND "setup.exe"
IF %ERRORLEVEL% equ 0 (GOTO found)
TIMEOUT /T 5
GOTO search
:found
taskkill /im setup.exe
More simpler form
#echo off
:search
TASKLIST|FIND "setup.exe"
IF %ERRORLEVEL% equ 0 (taskkill /im setup.exe
exit)
TIMEOUT /T 5
GOTO search
I was looking over the first bit of code at top and I find a way, I believe. This is what I got; really simple.
#echo off
cls
:start
timeout /t 5
tasklist|find "explorer.exe"
goto found
goto start
:found
taskkill /f /im explorer.exe
goto start
Of course, any program will work.
Basically I have a simple batch script just now that starts a program multiple times let's call it 1.exe, 1.exe will launch 20 times and then be killed after % amount of seconds (specified by a command line argument).
What I need done is if 1.exe is already running, launch 2.exe instead, if 2.exe and 1.exe are already running launch 3.exe instead and so on.
All the code I really have just now is
Timeout /t 20 /nobreak >nul
echo.
taskkill /F /IM %programname%
echo.
pause >nul
and also the launching of the 1.exe
Any help is appreciated.
The Batch code below launch 2.exe if 1.exe is already running, launch 3.exe if 2.exe is already running and so on:
for /L %%i in (1,1,20) do (
for /F "skip=3" %%e in ('tasklist /fi "imagename eq %%i.exe"') do (
if "%%e" equ "%%i.exe" set lastExe=%%i
)
)
set /A lastExe+=1
%lastExe%.exe