Batch to check if process exists - windows

I'd like a batch that will check if the process firefox.exe exists (after it has been started by the start command).
If the process exists, it will go to the label :fullscreen,
else the batch will go the the label :timeout. Then, it will check again if the process firefox.exe exists and if not, it will go again to the label :fullscreen until the process exists.
Here is my batch:
#echo off
start "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
:timeout
timeout /t 5
:fullscreen
nircmd sendkeypress F11
exit
How can I do this check ?

You can also use QUERY PROCESS:
#Echo Off
If Not Exist "%ProgramFiles(x86)%\Mozilla Firefox\firefox.exe" Exit/B
Start "" "%ProgramFiles(x86)%\Mozilla Firefox\firefox.exe"
:Loop
Timeout 5 /NoBreak>Nul
QProcess firefox.exe>Nul 2>&1||GoTo :Loop
NirCmd SendKeyPress F11

I suggest for this task the batch file:
#echo off
start "" /max firefox.exe
if errorlevel 1 goto :EOF
set LoopCount=0
:WaitLoop
%SystemRoot%\System32\timeout.exe /T 5
%SystemRoot%\System32\tasklist.exe /FI "IMAGENAME eq firefox.exe" 2>nul | %SystemRoot%\System32\find.exe /I "firefox.exe" >nul
if not errorlevel 1 nircmd.exe sendkeypress F11 & goto :EOF
set /A LoopCount+=1
if not %LoopCount% == 6 goto WaitLoop
Let me explain the few command lines used here.
1. Starting Firefox
The command START being an internal command of cmd.exe interprets the first double quoted string as optional title for the console window. Therefore the command line
start "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
results just in opening a new console window with the window title:
C:\Program Files (x86)\Mozilla Firefox\firefox.exe
For that reason "" is specified as first START argument to define an empty title. Firefox is a GUI application. So no console window is opened which means an empty window title is really enough.
The parameter /max would not be really necessary, but the goal is to get Firefox into full screen mode after starting. So why not starting it already maximized?
32-bit version of Firefox is by default installed in directory %ProgramFiles% on 32-bit Windows and in %ProgramFiles(x86)% on 64-bit Windows. But it is possible during the installation to install Firefox into any other folder. But Firefox installer is well coded and registers firefox.exe in Windows registry under key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
This is recommended by Microsoft as written in MSDN article Application Registration.
The command START searches also in Windows registry under this key for an executable specified as argument without path as explained in answer on Where is “START” searching for executables?
This is the reason for using just firefox.exe on START command line because that starts an installed Firefox independent on installation location.
START displays an appropriate message box if firefox.exe could not be started and exits in this case with a return code greater 0 (9059 in my test on one computer).
The help output on running if /? in a command prompt window explains how to evaluate the exit code of a previous command or application without usage of immediate or delayed environment variable expansion and therefore working anywhere in a batch file from MS-DOS (really!) to currently latest Windows 10.
The command line if errorlevel 1 goto :EOF means IF start failed to start firefox.exe indicated by an exit code greater or equal 1 THEN exit execution of this batch file. For details on exiting batch file execution see answer on Where does GOTO :EOF return to?
2. Checking for running Firefox
The command TASKLIST being an external command, i.e. a console application in system directory of Windows, outputs a list of running processes. This list can be already filtered by TASKLIST itself for a specific process as done in batch file with /FI "IMAGENAME eq firefox.exe".
But TASKLIST is designed for just printing a list of processes. It is not designed for checking if a specific process is running and returning the result to the calling process via exit code. TASKLIST always exits with 0.
But an error message is output to handle STDERR on using a filter and no process can be found in process list matching this filter. For that reason 2>nul is used to suppress this error message by redirecting it to device NUL. Read the Microsoft article about Using Command Redirection Operators for more information about redirection.
A simple method to get a simple false/true respectively 0/1 result on checking for running Firefox is filtering output of TASKLIST with external command FIND which exits with 0 if the string to find was indeed found or with 1 if the searched string could not be found in the text read in this case from STDIN. The output of FIND is of no interest and therefore suppressed with redirection to device NUL using >nul.
Instead of using TASKLIST and FIND it is also possible to use QPROCESS:
%SystemRoot%\System32\qprocess.exe firefox.exe >nul 2>&1
QPROCESS exits with exit code 1 if firefox.exe could not be found in list of running processes. Otherwise the exit code is 0 on firefox.exe is running.
3. Evaluating Firefox process checking result
if not errorlevel 1 nircmd.exe sendkeypress F11 & goto :EOF
The IF command checks if exit code of FIND is NOT greater or equal 1 which means if exit code is lower than 1. Command FIND exits never with a negative value. So if this condition is true then it is time to execute nircmd.exe to send key press F11 to application in foreground hopefully being Firefox (not guaranteed by this code) and exit batch file processing.
Otherwise the batch file should wait once again 5 seconds and then do the check again. This can very easily result in an endless running batch file in case of started Firefox is immediately closed by the user before the 5 seconds wait timed out. For that reason it is counted how often the wait loop is already executed. After 6 loop runs, or 30 seconds, it is really time to no longer wait for Firefox and exit the batch file.
4. Getting more information about used commands
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
find /?
if /?
qprocess /?
set /?
start /?
tasklist /?
timeout /?
And Single line with multiple commands using Windows batch file should be also read explaining operator & in addition to all other web pages referenced already above.

You can show a list of opened programs like this:
tasklist
To check if firefox exists:
EDIT: Code edited to show a fully working example
#echo off
start "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
goto :checkloop
:checkloop
tasklist|find "firefox.exe" > NUL
if %ERRORLEVEL% == 0 (
call :fullscreen
exit
) else (
call :timeout
goto :checkloop
)
:fullscreen
nircmd sendkeypress F11
goto :EOF
:timeout
timeout /t 5
goto :EOF

Related

How to execute multiple programs in the same time with a .bat file

I made 2 bat files to start apps with examples below:
My expectation is to execute them simultaneously, meaning after double click bat file, then 3 programs will pop up.
With the 1st example, the behavior is to execute outlook first, then both Mircrosoft Edge and OneNote still not pop up, until I stop Outlook.
Example 1
#echo off
"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Outlook.lnk"
"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk"
"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\OneNote.lnk"
exit
With the 2nd example, both Mrcrosoft Edge and OneNote were executed simultaneously, however Outlook not until I stop OneNote.
Example 2
#echo off
"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk"
"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\OneNote.lnk"
"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Outlook.lnk"
exit
My questions is why it behaves like this way and how to make these 3 programs start up in the same time ?
Shown below is the Windows config:
Edition Windows 10 Enterprise
Version 21H2
Installed on ‎10/‎27/‎2021
OS build 19044.1826
Experience Windows Feature Experience Pack 120.2212.4180.0
1)Run the first program using the start command.
2)Check the task list in a loop to see if the program has appeared there.
3)Impose some time limitation to the said loop.
4)Run the next program in case of success, exit with notification otherwise.
#ECHO
OFF START program1.exe
FOR /L %%i IN (1,1,100) DO (
(TASKLIST | FIND /I "program.exe") && GOTO :startnext
:: you might add here some delaying
)
ECHO Timeout waiting for program1.exe to start
GOTO :EOF
:startnext
program2.exe
:: or START
program2.exe
Remember that the timing is not precise, especially if you are going to insert delays between the task list checks.
Normally to run tasks parallel, you should add start /b before the command to run.
The start command allows the command to be executed in another process, while /b prevents the opening of a new window.
In this specific case start /b does not work, for reasons unknown to me, but you can always use cmd /c.

Starting a batch file in a new window from a batch file, and keeping the new window open after completion

EDIT: I will try to make it clearer what I actually want.
I have some very long batch files that I want to run in order and only starting after the previous one had completed.
I am trying to control this with a master batch file
I want them starting each in their own window which remains open after completion to look back later
In numerical order:
1.run main batch file
2.open new cmd window
3.run batch file 1
4.waiting for 1 to finish
5.1 finished, keep window open
6.open another new cmd window
7.run batch2
etc
-- original message --
Hi so I have a windows batch file that needs to run other windows batch files sequentially and wait for them to finish before starting the next one.
Something like:
#echo off
setlocal EnableDelayedExpansion
SET RUN="C:first.bat"
start /wait cmd /c %RUN%
SET RUN="C:second.bat"
start /wait cmd /c %RUN%
where first and second for example just echo something like:
#echo off
echo 1st
exit /b 0
When I run this it starts the first script in a new window and keeps the window open after completing like I want, but to progress to the second script I have to close the new cmd window.
How can I make the main batch script start the second.bat without closing the first.bat cmd window?
Thanks
It is a very unusual requirement that
other batch files should not be processed by the cmd.exe instance processing the main batch file, but by other instances of cmd.exe just to have their outputs in a different console window and
keep each other command process running after finishing the processing of the batch file to be able to view their outputs in their console windows and
wait with further processing of main batch file until processing of a batch file finished by the started separate command process, but do not wait for termination of the started other command processes.
The Windows command processor cmd.exe is not designed for a serialized multi-processing of batch files with multiple instances of itself which finally should keep running.
However, here are three batch files which demonstrate that this is possible with one disadvantage explained later.
Main.bat
#echo off & goto Main
:WaitForBatch
start "Run %~nx1" %ComSpec% /D /S /K "(%ComSpec% /D /C "%~1") & title Finished %~n1"
echo Waiting for finished execution of "%~nx1" ...
:CheckBatchRun
%WaitCommand% >nul
%SystemRoot%\System32\tasklist.exe /NH /FI "IMAGENAME eq cmd.exe" /V | %SystemRoot%\System32\find.exe /I "%~nx1" >nul
if errorlevel 1 goto :EOF
goto CheckBatchRun
:Main
setlocal EnableExtensions DisableDelayedExpansion
title Run %~nx0
if exist %SystemRoot%\System32\timeout.exe (
set "WaitCommand=%SystemRoot%\System32\timeout.exe /T 1"
) else (
set "WaitCommand=%SystemRoot%\System32\ping.exe 127.0.0.1 -n 2"
)
call :WaitForBatch "%~dp0First.bat"
call :WaitForBatch "%~dp0Second.bat"
title Finished %~n0
pause
endlocal
First.bat
#echo off
dir %SystemRoot% /B /S
Second.bat
#echo off
dir %SystemRoot%\*.exe
echo/
pause
Main.bat is coded in a manner expecting First.bat and Second.bat in the same directory as Main.bat, but the other batch files can be also in different directories. The current directory on execution of the three batch files can be any directory.
Main.bat first sets up the execution environment for itself which is:
command echo mode turned off and
command extensions enabled and
delayed expansion disabled.
The window title of the console window of cmd.exe processing Main.bat is modified to show Run Main.bat at beginning.
Next is determined if command TIMEOUT is available in which case this command will be used later for a delay of one second (Windows Vista and later Windows client versions) or if command PING must be used for the one second delay (Windows XP).
Then the subroutine WaitForBatch is called the first time with the batch file First.bat.
The subroutine uses the command START to start one more command process in a new console window with window title Run First.bat with ignoring the AutoRun registry string value which by Windows default does not exist.
This second cmd.exe instance keeps running after execution of the command line specified next with the other arguments is finished. The command line for second cmd.exe requires the execution of a third cmd.exe again with ignoring AutoRun registry string value if existing at all to execute the batch file First.bat specified with fully qualified file name. The third cmd.exe instances closes itself on finishing processing of the batch file.
The second cmd.exe changes now the title of its console window to Finished First. Important is here that the batch file extension is not anymore in the window title.
The first cmd.exe instance processing Main.bat continues with batch file processing already after successful start of second cmd.exe. It uses the command to wait one second and then runs TASKLIST to output all running cmd.exe processes with verbose information which is redirected to command FIND to search case-insensitive for the batch file name First.bat.
As long as there is a cmd.exe process running with First.bat, the first cmd.exe continues batch file processing of Main.bat inside subroutine WaitForBatch in a loop with a jump to CheckBatchRun. Otherwise the subroutine is left and processing of Main.bat continues with the second CALL of WaitForBatch with Second.bat.
Finally Main.bat changes also its window title to Finished Main and prompts the user to press any key in case of Main.bat execution was started with a double click on this file in Windows Explorer.
First.bat takes a very long time to finish as thousands of file names must be output into the console window of second cmd.exe. It is possible to click on the X symbol of console window with title Run First.bat to terminate immediately the execution of second and of third cmd.exe which results in first cmd.exe continues with starting two more cmd.exe for processing Second.bat.
It is also possible to interrupt the long running First.bat by pressing Ctrl+C and answer the prompt for termination of batch job with Y (on English Windows) resulting in third cmd.exe stopping really the processing of First.bat and second cmd.exe keeps running showing the output of First.bat and changing the window title of its console window to Finished First. This is detected by first cmd.exe processing Main.bat and it starts the processing of Second.bat.
The disadvantage of this solution is that on pressing Ctrl+C in console window with title Run First.bat while DIR outputs all the file names and pressing now N (on English Windows) results nevertheless in a termination of the batch job. I am not 100% sure why this happens. I have just a supposition for this behavior.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
cmd /?
dir /?
echo /?
endlocal /?
find /?
goto /?
if /?
pause /?
ping /?
setlocal /?
start /?
tasklist /?
timeout /?
title /?

How to run batch files in background while running multiple files in parallel

I am writing a batch file which will execute 4 other batch files in parallel:
#echo off
echo %time%
(
start call s1.bat
start call s2.bat
start call s3.bat
start call s4.bat
) | set /P "="
echo %time%
But this is opening 4 new windows.
Can anyone help, how to avoid opening multiple windows and run all those 4 batch files in background?
Adding /B is on of the option, but I don't to where to add it exactly.
(
start /B call s1.bat
start /B call s2.bat
start /B call s3.bat
start /B call s4.bat
) | set /P "="
Is giving me an error:
The process tried to write to a nonexistent pipe.
As I do not want to use VB or any other script, how to do it in batch?
This is a really interesting problem! It seems that there is some conflict with the redirection handles.
The main script awaits execution of the sub-scripts with the following code (on Windows 10):
(
> nul start "" /B cmd /D /C call s1.bat
> nul start "" /B cmd /D /C call s2.bat
> nul start "" /B cmd /D /C call s3.bat
> nul start "" /B cmd /D /C call s4.bat
) | set /P =""
The > nul redirection prevents any data to be written to the pipe |. It seems as soon as there becomes anything written to the standard output handle STDOUT (1), the main script does no longer wait (and sometimes the error message The process tried to write to a nonexistent pipe. arises, possibly depending on how fast the sub-script(s) execute(s)). However, as soon as the /B is removed, output to STDOUT by the sub-scripts does not affect the behaviour of the main script, which waits for all sub-scripts, and > nul is therefore no longer necessary.
The explicit cmd /C part is necessary because start would otherwise implicitly use cmd /K when starting internal commands like call which leave non-terminated processes cmd.exe behind upon completion of the respective sub-script.
The /D switch just prevents any auto-run commands to become executed.
When you use normal start without /B for running the sub-scripts, a new instance of the command interpreter is started, that is the process cmd.exe, and a new instance of the console window is started as a process conhost.exe.
Now using start /B still creates a new process cmd.exe but it uses the current process conhost.exe.
I do not know what exactly happens in the background and how all these processes interact, but it appears to me that the issue is connected to the lack of conhost.exe processes when using start /B. Maybe conhost.exe is establishing the redirection handles and hence the pipe. Anyway, as long as there is nothing written to the pipe, there is nothing to conflict, so set /P ="" waits for the related handle to become closed.

Batch file to close program after second program opens

I have a frontend program (a.exe) that I use to curate and launch other programs (in this example b.exe). Once the item in the frontend (a.exe) is selected from the list (b.exe) launches. Problem is the frontend (a.exe) stays open and to close it I have to manually exit out of the program it launched (b.exe) to the desktop to do so.
What I am trying to do is have the frontend (a.exe) close after an item within it is selected (b.exe). This would be trigged by a double click.
How would I go about creating a batch file to do this?
The frontend program (a.exe) has a GUI interface.
#echo off
cd "C:\Program Files\a.exe folder"
start a.exe
then what?
The best solution would be contacting the author of a.exe and asking for an option to automatically exit a.exe after starting application b.exe as separate and detached process.
The second best solution would be finding out which environment b.exe needs to run successfully and create with a batch file this environment and start b.exe.
However, if the best two solutions are not possible for whatever reason, then the following batch file code be helpful.
#echo off
start "" /D"C:\Program Files\a.exe folder" "a.exe"
set "LoopCount=0"
:Loop
%SystemRoot%\System32\timeout.exe /T 1 /NOBREAK >nul
%SystemRoot%\System32\tasklist.exe /NH | %SystemRoot%\System32\findstr.exe /B /C:"b.exe" /C:"c.exe" /C:"d.exe" >nul
if not errorlevel 1 (
%SystemRoot%\System32\taskkill.exe /IM "a.exe"
goto EndBatch
)
%SystemRoot%\System32\tasklist.exe /NH | %SystemRoot%\System32\findstr.exe /B /C:"a.exe"
if errorlevel 1 goto EndBatch
set /A LoopCount+=1
if not %LoopCount% == 60 goto Loop
:EndBatch
set "LoopCount="
The batch file first starts a.exe with its program files directory set as current directory before starting it as separate process.
Windows command processor immediately continues execution of the batch file after starting a.exe and defines next the environment variable LoopCount with value 0.
Inside the loop the external command TIMEOUT available since Windows Vista by default is used to wait one second.
Then external command TASKLIST is executed to output all running processes without header. This output is redirected with | to external command FINDSTR which searches case-sensitive at beginning of all lines output by TASKLIST for one of the strings specified with the option /C:. For a case-insensitive search use additionally FINDSTR option /I if not knowing how the executables started by a.exe are in list output by TASKLIST.
FINDSTR exits with value 0 on having found at least one line starting with one of the searched strings and with value 1 if nothing matched. The output of FINDSTR is of no interest and therefore redirected to device NUL.
The terminate signal is sent with external command TASKKILL to the executable a.exe on having found one of the processes in the list. a.exe should terminate itself on receiving and processing this signal. In case of a.exe is ignoring this signal or it terminates, but before terminates also the started application, it would be necessary to use additionally the TASKKILL option /F to force a real kill of a.exe process by the Windows operating system. In general the option /F should not be used as it can result in corrupt files in case of application killed by the operating system has one or more files open for write operations.
But if after one second none of the processes started by a.exe is running, the batch file checks next if a.exe itself is still running. The batch file exits if this is not the case. Otherwise it increments the environment variable LoopCount and compares its value with 60 to exit batch file after having waited already 60 seconds with the checks to avoid a nearly endless running batch file.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
findstr /?
goto /?
if /?
set /?
start /?
taskkill /?
tasklist /?
timeout /?
See also Microsoft article about Using command redirection operators.

Need a batch file to start, delay a close, and restart another batch file.

I have searched and searched and this is the closest code I have found:
#echo off
:loop
C:\CryptoCurrency\nexus_cpuminer\start.bat
timeout /t 30 >null
taskkill /f /im nexus_cpuminer.exe >nul
goto loop
A few things: notice the start.bat. The .exe I need to launch has to start via the .bat file because the .bat file contains information the .exe needs.
Secondly, the .exe launches a CMD prompt window which shows me what's going on.
(keep this in mind because this is not your normal .exe, I WANT that CMD prompt window to close when it's KILLED)
I am aware I have it set for 30 seconds. I'm just testing right now. I'd like to set it for 4 hours before the kill command is called. Also, I'd like to set a "delay" of 30 seconds before the whole process starts over. I am running Windows 7 x 64.
You must change the name of the second Batch file to other name (i.e. starter.bat) and execute it via the start internal command in order to execute it in parallel:
#echo off
:loop
start "" cmd /C "C:\CryptoCurrency\nexus_cpuminer\starter.bat"
timeout /t 30 >null
taskkill /f /im nexus_cpuminer.exe >nul
goto loop
The last line in starter.bat file must be the execution of nexus_cpuminer.exe, so when it is killed via taskkill, the .bat file ends immediately.
Another simpler approach is to directly execute nexus_cpuminer.exe in this Batch file, via start "" cmd /C nexus_cpuminer.exe command, so this process be opened in its own cmd.exe window.
If you CALL start.bat, it will return to your 'calling' script.
If you give start.bat a TITLE, you can /FIlter your TASKKILL command to EQ that WINDOWTITLE

Resources