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
CodePudding user response:
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 ofcmd.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 /?