I am running 1 st batch utility calling another 2nd batch. The 2nd batch calls a setup.cmd command which has internal Java code to patch files.
When I just call the 2nd batch from 1st batch --
1st batch calls the second batch
2nd batch calls the setup.cmd
1st batch continues with further code without waiting for setup.cmd to complete.
I tried using start /wait to call the setup.cmd but that does not returns back the control to 1st batch. It keeps the session after installing.
1st batch calls 2nd batch by using CALL
2nd batch has following code to call setup.cmd
%windir%\system32\cmd /c start /WAIT Disk1\setup.cmd %parameter%
How can I get the control back to 1st batch once the setup.cmd completes?
If you just use this without the start command, and call batch2 then it will wait until it is finished.
call Disk1\setup.cmd %parameter%
Resolved this last week by using loops and by calling the setup.cmd...sorry for delay in this post.
#echo off
CALL \Installers\Disk1\setup.cmd -i silent -FILE=\Silent\Silent.txt
:LOOP
tasklist /FI "username eq SOMEUSER" 2>NUL | find /I /N "java">NUL
ECHO %ERRORLEVEL%
if "%ERRORLEVEL%"=="1" (
GOTO CONTINUE
) ELSE (
ECHO PATCH is still running, Sleeping for 5 Mins
SLEEP 300
GOTO LOOP
)
:CONTINUE
Related
This question already has answers here:
Start multiple tasks in parallel and wait for them in windows?
(2 answers)
Closed 2 years ago.
I have a batch scripts that starts multiple processes (partly other batch files) in background via
start /b /min command1.exe some params
start /b /min command2.bat some params
start /b /min command3.exe some params
at the end of the top level batch script I would like to wait until all processes are completed.
Is there any way to achieve this without implementing special means within the called programs?
You can create special batch file that runs another process, waits for it to finish and creates a special file. Then launch desired processes with this script without wait and loop until all files are created.
Sample code for inspiration:
Runner.bat:
:: Run, wait and create file; %1 = file name, %2..N - process and params
set FileName=%1
shift
start /b /min /wait %* && (echo OK > %FileName%) || (echo Fail > %FileName%)
Main.bat:
call Runner.bat No1 command1.exe some params
call Runner.bat No2 command2.bat some params
...
:Check
... if not exist "No1", "No2", ... (
timeout /t 5
goto :Check
)
One option is to try to start them with WMIC process call create "c:\some.exe","c:\exec_dir" and assign the created PID to variable and checking periodically that the PIDs are existing.
You can try also with :
(
start "" /b command1
start "" /b command2
)|findstr "^"
echo all processes in the brackets block have ended
but if some of the commands is bat file you explicitly'll have to use exit 0 without /b switch.
I am trying to run a .bat script from the Command Prompt. However, once the script ends I want to either run the bat script again automatically or go back to the path and just manually enter the bat script name, and just run it again. Either one of those would be good.
I tried using pause or just using exit but it didn't work.
Batch Script:
#echo off
title runner
set /p man=
if %man% == 1 goto Kane
:1
echo Hello Kane
pause
exit
Academic Answer
It is possible to have cmd replace itself in a sense when launching another cmd script.
"%~0" %*
This will invoke itself and not return.
(Merely using %* will not work correctly in any of the command-line arguments passed to this script needed quoting or escapes. You'd have to construct your own loop to handle that, if needed.)
Example
#ECHO OFF
#ECHO Start: %LOOP_COUNT%
SET /A LOOP_COUNT=LOOP_COUNT+1
IF "%LOOP_COUNT%" GEQ "5" (
#ECHO Finished.
EXIT /B
)
#ECHO Looping: %LOOP_COUNT%
"%~0"
#ECHO THIS SHOULD NEVER HAPPEN
This script will invoke itself, incrementing LOOP_COUNT every time, until it reaches 6. Then it will quit.
Notice that the last line of the script will never execute because the running script is "replaced" (IDK the cmd parlance for this concept).
Note: If you wouldn't want to replace the script (which is almost always what I want), you'd use CALL "%~0" to invoke it, rather than just invoking it directly (i.e. "%~0").
When I run the above script (I called it loop.cmd), I get:
c:\work\nsa_eavesdropping\scripts>loop.cmd
Start:
Looping: 1
Start: 1
Looping: 2
Start: 2
Looping: 3
Start: 3
Looping: 4
Start: 4
Finished.
EXIT [/B]
It's usually preferable to use the /B parameter for EXIT so that the only the script execution is exited, not the calling shell process. There could be occasions for immediately killing the calling shell process, but most of the time, EXIT /B is the behavior I want.
Why an infinite loop??
That being said, it may be that there's a better way to solve the problem than an infinite loop.
I need to know how can I check in batch file if the second batch file which is opened in other command window has stopped (waiting for argument or process not successful).
#echo off
:loop
start /wait rapidminer-batch.bat -f C:\Users\AHM-PC\Documents\ccc.rmp
echo cmd stopped
pause
goto loop
When called batch ends, it returns a value to errorlevel. It works for call, don't know if for start too.
if %errorlevel% gtr 0 (
echo failed
) else (
echo success)
or call exit /b <number of error> in your called batch, to return specific value. Check exit for more details.
The normal method to provide interbatch communication is a flag file
Either you create a flag file in the main routine and wait for the started routine to delete it or wait until the started batch creates a file, and delete it.
eg
echo.>myflag.txt
start anotherbatch.bat
:loop
timeout /t 1 >nul
if exist myflag.txt goto loop
Here, the batch will wait until myflag.txt is deleted, which you do in the second batch. All you need is for the two routines to agree on a filename to use.
I hope that makes sense. I want to create a batch file or anything similar that will cycle through a few Processing applications for a presentation. Is there a way I can do this that will execute an application by time intervals, close before executing the next one, and then cycle back to the first application?
Certainly.
#ECHO OFF
SETLOCAL
:loop
FOR %%i IN ("process1.exe 20" "process2.exe 30" "process3.exe 10") DO CALL :cycle %%~i
GOTO loop
:cycle
START %1
timeout /t %2 >nul
TASKKILL /im %1 >nul
GOTO :eof
runs process1 for 20 sec, process2 for 30 - Got the pattern? The processes are terminated unceremoniously.
Press control-C and reply Y to terminate - will leave the last process invoked running.
Addendum:
TASKKILL knows nothing about "paths" - only the executable name.
hence, on the line after after the setlocal add
set path=C:\Users\MyName\Documents\School\Processing\Sketch_8\application.windows32;%path%
and specify the executable only in the FOR statement.
If there's more than one directoryname involved, just string them together with ; separators and ;%path% at the end.
Windows picks up the executable from the path by looking first in the current directory, then each directory on the path in turn until it finds the required executable. Adding the extra directories occurs only for the time this batch is running, and applies only to the batch's instance - it's not transmitted to any other process.
I want to perform the following operations.
Read 1 word at a time from an input file consisting of many words.
Pass this word as an argument to another command line based application.
Run that application for a fixed amount of time, say 10 seconds.
Abort the execution of the application if it is still running after 10 seconds and go back, pick the next word from the input file and repeat steps 1 to 3.
Here is what I have written though it does not achieve exactly what I want it to:
#echo off
for /f %%i in ('type input.txt') do call:Routine %%i
:Routine
set app="myApp.exe"
set limit=60
%app% %1
goto Delay
:Delay
ping localhost -n %limit% > nul
The above script will introduce the delay after the execution of myApp has completed. However, I want it to run myApp.exe for not more than 10 seconds, if it does, then abort the application using taskkill and move on to the next word from the input file.
I searched for a solution online and came across this:
http://www.tech-archive.net/Archive/WinXP/microsoft.public.windowsxp.general/2006-04/msg03609.html
Though it does not answer my query exactly, I would like to make my code do something similar.
Thanks.
The logic in the linked code looks flawed: It either launches 3 download commands, or it delays ~59 seconds and attempts to kill all download commands, but it never does both. The TASKKILL command arguments are not correct - the imagename belongs after the /IM parameter.
In your code, you are not going to kill your task without the TASKKILL command!
You must GOTO :EOF or EXIT /B after your loop finishes, otherwise the code will fall through and execute the subroutine without using CALL. But there really is no need to use a subroutine at all.
You only need to initialize your variables once.
No need to execute a command in your IN() clause. FOR /F has a variation that can read the text file directly. Type HELP FOR from the command line and read the documentation carefully.
PING has roughly a 1 second delay between each echo request. So a count of 11 will yield a delay of roughly 10 seconds.
EDIT - originally forgot the critical START command to start the app in its own process
#echo off
set app="myApp.exe"
set limit=11
for /f %%i in (input.txt) do (
start "" %app% %%i
ping localhost -n %limit% > nul
taskkill /im %app% /f
)