I am wanting to run a batch file which builds visual studio project in another window and then return to original window and execute later commands.
but following command immediately prints LetterTwo without waiting for complete solution building
echo LetterOne
start /WAIT msbuild sim.sln
echo LetterTwo
According to the comments to the question, it seems, msbuild doesn't behave, like one would guess. So your only way is to "wait manually":
start "MyUglyApplication" msbuild sim.sln
:loop
timeout 1 >nul
tasklist /v | find "MyUglyApplication" && goto :loop
echo finished.
Give the new window a unique name, test if the process is running and if yes, continue testing.
i have able to solve the problem by modifying #stephan code a little bit
#echo off
start msbuild <solution>
:loop
timeout 1 >nul
tasklist /FI "IMAGENAME eq msbuild.exe" 2>NUL | find /I /N "msbuild.exe">NUL
if "%ERRORLEVEL%"=="0" goto loop
echo finished.
Related
So this bat file was running perfectly right before this latest windows update.
#Echo off
:Start
Start E:\directoryhere?listen -dedicated
echo Press Ctrl-C if you don't want to restart automatically
ping -n 10 localhost
goto Start
So this would start a dedicated server. A command prompt would pop up. When everyone left the server or the game finished, the command prompt would close then the .bat file would reopen it. Now after this update, the .bat file just keeps opening the cmd prompt while its open. So i'll have instantly 20 instances open at once and my cpu is at 100%.
I've also had this code before the windows update before this one which ended up doing the same thing.
#echo off
cd "E:\directoryhere\"
:loop
Start RxGame-Win64-Test.exe server lv_canyon?listen -dedicated | set /P "="
goto loop
That code used to work, but 2 window updates before ended up doing the same thing. It would just keep opening instances and make my cpu 100%.
What's a way to make sure to see if the cmd prompt is open and not to reopen it and keep it running until the cmd prompt closes then reopen it.
A simple fix to this can to check is the process already is open first using tasklist. Please make sure you search what your actual application is called. For this example I'm going to guess it's called RxGame-Win64-Test.exe. Bellow are a few script options.
This script bellow will check to see if the RxGame-Win64-Test.exe app is open first before starting another one:
#ECHO OFF
#SETLOCAL enabledelayedexpansion
GOTO LOOP
:LOOP
Rem | Check If Window Is Open
tasklist /FI "IMAGENAME eq RxGame-Win64-Test.exe" 2>NUL | find /I /N "RxGame-Win64-Test.exe">NUL
if not "%ERRORLEVEL%"=="0" (
Rem | Process Not Found
timeout /T 10 /NOBREAK
Rem | Restart Server
start "" "RxGame-Win64-Test.exe server lv_canyon?listen -dedicated"
Rem | GOTO LOOP
GOTO LOOP
)
GOTO LOOP
Not sure if the RxGame-Win64-Test.exe is CMD based program or not but if it is the script bellow will help you:
#ECHO OFF
#SETLOCAL enabledelayedexpansion
Rem | First Load, Start Server
start "DedicatedServerLauncher" cmd /c "RxGame-Win64-Test.exe server lv_canyon?listen -dedicated"
GOTO LOOP
:LOOP
Rem | Reset PID
Set "PID="
Rem | Grab The Current Window PID
FOR /F "tokens=2" %%# in ('tasklist /v ^| find "DedicatedServerLauncher" ^| find "Console"') do set PID=%%#
Rem | Check If Window Is Open
if "!PID!"=="" (
Rem | Process Not Found
timeout /T 10 /NOBREAK
Rem | Restart Server
start "DedicatedServerLauncher" cmd /c "RxGame-Win64-Test.exe server lv_canyon?listen -dedicated"
Rem | GOTO LOOP
GOTO LOOP
)
GOTO LOOP
For help on any of the commands do the following:
call /?
set /?
for /?
if /?
find /?
So on.
I am trying to write a batch script that detects if an .exe is not responding, and if it isn't, it will run a piece of code that kills it and then does some other things as well. I know how I can kill the process and restart it if it is not responding in one line, but I am not sure how I can do more than just restart it by converting this into an if statement, or calling a goto.
taskkill /im "exeName.exe" /fi "STATUS eq NOT RESPONDING" /f >nul && start "" "pathToExe"
I have come across other Stack Overflow posts that are similar to this, however they only check the error level of the process and do not check if the program is not responding and how to perform code after that.
How would I go about this? Thanks in advance.
Assuming I am interpreting your question correctly and you want to test without killing a task, how about this:
tasklist /fi "status eq not responding" /nh | find "exeName.exe" >NUL
if %errorlevel% == 0 (
echo Oops, we've hung...
)
tasklist takes the same /fi status options as taskkill, even though the documentation states only RUNNING is allowed - taskkill /? on Windows 8 at least shows the full options. We then use find to check that the executable is in the list of not responding tasks.
BTW, if you want to use PowerShell instead:
$foo = get-process exeName
if (!$foo.Responding) {
echo "Oops, we've hung..."
}
Can be done more easily:
taskkill /FI "STATUS eq NOT RESPONDING" /IM "yourexe.exe" /F | findstr /c:"SUCCESS" >nul
if %errorlevel% EQU 0 (echo Successfully detected and terminated "yourexe.exe" which didn't respond) else (echo Ooops! We didn't find or could not terminate process "yourexe.exe")
If you want to just detect if process is not responding, then use tasklist:
tasklist /FI "STATUS eq NOT RESPONDING" | findstr /c:"yourexe.exe">nul
if %errorlevel% EQU 0 (echo We have detected that process with image name "yourexe.exe" is not responding.) else (echo We didn't found process with image name "yourexe.exe" because it doesn't exist.)
In both cases we use findstr command because even if process not found/terminated taskkill/tasklist will return errorlevel 0.
I want a batch script that checks if the program is in running or not responding state. If it is in running state exit the batch script, else kill the program start the other application.
I tried using the following code but it is executing opening application even though the program is in running state. Please help me in finding a solution
#echo off
TASKLIST/IM jusched.exe /FI "STATUS eq NOT RESPONDING">nul /T /F && start "" notepad.exe
You appear to be mixing up the TaskKill and TaskList syntax. (Enter TaskList/? and TaskKill/? at the command prompt for usage information). Also I think TaskList output is always successful so it would probably need to be checked using something which does register if unsuccessful, e.g. Find.exe.
Here is a basic step by step example for you.
#Echo Off
Rem Setting name of target process
Set "TP=jusched.exe"
Rem Setting name of new process
Set "NP=notepad.exe"
Rem Setting TaskList filters to reduce line length
Set "F1=ImageName eq %TP%"
Set "F2=Status eq Not Responding"
Rem Check target process status and exit if no match
TaskList /FI "%F1" /FI "%F2%" /NH|Find /I "%TP%">Nul||Exit/B
Rem Kill unresponsive process and wait a little
TaskKill /IM "%TP%" /T /F>Nul 2>&1&&Timeout 3 /NoBreak>Nul
Rem Open new process
Start "" "%NP%"
I want to start two programs from the batch file, (also batch files) - they will execute few seconds. Then in the main batch file I want to wait while both are finished and then continue main execution. Is that possible at all?
You can, sort of:
#echo off
set Token=MAIN_%RANDOM%_%CD%
start "%Token%_1" cmd /c child1.cmd
start "%Token%_2" cmd /c child2.cmd
:loop
ping -n 2 localhost >nul 2>nul
tasklist /fi "WINDOWTITLE eq %Token%_1" | findstr "cmd" >nul 2>nul && set Child1=1 || set Child1=
tasklist /fi "WINDOWTITLE eq %Token%_2" | findstr "cmd" >nul 2>nul && set Child2=1 || set Child2=
if not defined Child1 if not defined Child2 goto endloop
goto loop
:endloop
echo Both children died.
child1 and child2 were just executing pause. This uses a more or less unique token to identify the child batch files. They are started in an own window with start and each one is given a specific window title. Using that window title we can find them again using tasklist and determine whether they are still running.
It gets a little tricky figuring out whether the batch files are still running. tasklist with the window title filter does what it's supposed to do, but it won't return a sensible errorlevel. That's why we have to pipe through findstr to pick up the process name (to avoid being language-sensitive by picking up the error message).
I have 4 batch files. I want to run one.bat and two.bat at once, concurrently. After completion of these two batch files, three.bat and four.bat should run at once, in parallel. I tried with many ways but mot works fine.
Can anyone help me over this?
This is easily done using a much simplified version of a solution I provided for Parallel execution of shell processes. Refer to that solution for an explanation of how the file locking works.
#echo off
setlocal
set "lock=%temp%\wait%random%.lock"
:: Launch one and two asynchronously, with stream 9 redirected to a lock file.
:: The lock file will remain locked until the script ends.
start "" cmd /c 9>"%lock%1" one.bat
start "" cmd /c 9>"%lock%2" two.bat
:Wait for both scripts to finish (wait until lock files are no longer locked)
1>nul 2>nul ping /n 2 ::1
for %%N in (1 2) do (
( rem
) 9>"%lock%%%N" || goto :Wait
) 2>nul
::delete the lock files
del "%lock%*"
:: Launch three and four asynchronously
start "" cmd /c three.bat
start "" cmd /c four.bat
I had this same dilemma. Here's the way I solved this issue.
I used the Tasklist command to monitor whether the process is still running or not:
:Loop
tasklist /fi "IMAGENAME eq <AAA>" /fi "Windowtitle eq <BBB>"|findstr /i /C:"<CCC>" >nul && (
timeout /t 3
GOTO :Loop
)
echo one.bat has stopped
pause
You'll need to tweak the
<AAA>, <BBB>, <CCC>
values in the script so that it's correctly filtering for your process.
Hope that helps.
Create a master.bat file that starts one.bat and two.bat. When one.bat and two.bat end correctly, they echo to file they have finished
if errorlevel 0 echo ok>c:\temp\OKONE
if errorlevel 0 echo ok>c:\temp\OKTWO
Then the master.bat wait for the existence of the two files
del c:\temp\OKONE
del c:\temp\OKTWO
start one.bat
start two.bat
:waitloop
if not exist c:\temp\OKONE (
sleep 5
goto waitloop
)
if not exist c:\temp\OKTWO (
sleep 5
goto waitloop
)
start three.bat
start four.bat
Another way is to try with the /WAIT flag
start /WAIT one.bat
start /WAIT two.bat
but you don't have any control on errors.
Here's some references
http://malektips.com/xp_dos_0002.html
http://ss64.com/nt/sleep.html
http://ss64.com/nt/start.html
Just adding another way, maybe the shortest.
(one.cmd | two.cmd) && (three.cmd | four.cmd)
Concept is really straight forward. Start one and 2 in paralel, once done and errorlevel is 0 run three and four.