Batch Detecting Program Not Responding - batch-file

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.

Related

Need to Get Process Name From Changing PID Using Batch File

I am having random Applications Freeze up, while I can easily end unresponded tasks with the batch file, I am trying to diagnose which applications are causing the problems. But I cannot Reference a task that has already been killed by PID. I would like the code to show offending Applications before or after killing the process.
This is what I've been using up till now, it does work and does show the PID. But it does not show the application name.
#echo off
:Start
taskkill /f /fi "status eq not responding"
TIMEOUT /t 30 /nobreak
goto Start
**This is what i've been trying to use to get the offending application name**
:Start
Set %processPID% = taskkill.exe /fi "status eq not responding"
wmic process where "ProcessID=%processPID% get CommandLine, ExecutablePath
taskkill.exe /f /fi "status eq not responding"
TIMEOUT /t 5 /nobreak
goto Start
This is what I get when running the new code
It appears that the variable processPID is not being set.
C:\Users\razra\Desktop>Set = taskkill.exe /fi "status eq not responding"
The syntax of the command is incorrect.
C:\Users\razra\Desktop>wmic process where "ProcessID= get CommandLine, ExecutablePath
, - Invalid alias verb.
If you are willing to try PowerShell, you can achieve the same functionality.
Loop trough the processes having Responding property false.
Stops the process by ID.
Foreach($proc in Get-Process | Where-Object {$_.Responding -eq $false}){
Write-Host $proc.ID, $proc.Name
Stop-Process $proc.ID
}
Save the code with ps1 extension and run with PowerShell.exe -File <path>

Batch script to find if program is not responding and then start another application else exit batch job

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%"

start command in batch file

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.

Loop in batch not working

I've written a batch file that checks if only one instance of a server is running at any given time. The server is on a shared folder on a cloud, where multiple users have access to it.
If the server is running, a .txt file will be created, and as long as it's there, no one can start the server. When the server shuts down, the .txt file is deleted and another user is free to start it again.
minecraft_server.1.8.1.exe starts a Java process javaw.exe, which is the process that we need to monitor.
The code goes like this:
#echo off
IF EXIST *_RUNNING.txt (
echo "ERROR, SERVER ALREADY RUNNING as %computername%"
pause
EXIT
) ELSE (
copy NUL %computername%_RUNNING.txt
START /WAIT minecraft_server.1.8.1.exe
tasklist /FI "IMAGENAME eq javaw.exe" 2>NUL | find /I /N "javaw.exe">NUL
:loop
IF "%ERRORLEVEL%"=="0" (
TIMEOUT /t 60
GOTO loop
) ELSE (
del %computername%_RUNNING.txt
echo "Server ended."
pause
EXIT
)
)
Everything works except the loop. It keeps returning ") was unexpected at this time".
I'm new to writing batch files so please help.
#echo off
IF EXIST *_RUNNING.txt (
echo "ERROR, SERVER ALREADY RUNNING as %computername%"
pause
EXIT
)
copy NUL %computername%_RUNNING.txt
START /WAIT minecraft_server.1.8.1.exe
:loop
tasklist /FI "IMAGENAME eq javaw.exe" 2>NUL | find /I /N "javaw.exe">NUL
IF "%ERRORLEVEL%"=="0" (
TIMEOUT /t 60
GOTO loop
)
del %computername%_RUNNING.txt
echo "Server ended."
pause
EXIT
Effectively, you have a label :loop in a block (a parenthesised sequence of statements) in your original. Labels terminate blocks.
With these modifications, the unnecessary else clauses have been removed. If batch exits or gotos then the else is not required - the next statements in the batch will be executed if the goto/exit doesn't happen.
Note that your label :loop is in the wrong place. As it stood, errorlevel would be established for the first and only invocation of tasklist. Thereafter, the loop would perpetually find errorlevel 0 if it was set to 0 on the first instance. Moving it to the indicated location would execute tasklist/find with a delay of 60 sec until errorlevel became non-zero, when the non-goto path to terminate the procedure would be taken.
(not tested, of course...)

Can you fork in Windows batch file?

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).

Resources