I am trying to monitor if a batch is running or not and if it is not the case send an email.
I am using the following code :
Set "MyProcess=cmd.exe"
Set "taskToMonitor=taskToMonitor"
tasklist /NH /FI "WindowTitle eq %taskToMonitor%" 2>nul |find /i "%MyProcess%">nul
If not errorlevel 1 (Echo "%MyProcess%" est en cours d'execution) else (Powershell.exe -File D:\tmon-agent\MonitoringAgent\Mailsend.ps1)
This is sending me a mail if the batch is not running, but also if the batch is having an error even if it is still runing, which is not what i need.
Is it possible to check if the batch is runing without checking the errorlevel ?
Thanks
Related
I have a problem on checking the running state of another batch file using the command TASKLIST and continue processing the batch file depending on the result.
This is the code of my batch file which should check the running state of the other batch file:
#echo off
tasklist /FI "WINDOWTITLE eq C:\Windows\system32\cmd.exe - C:\ruta\ejecucion_prueba.bat" /FI "STATUS eq running"
if eq = running "not happening"
if ne = running "start C:\ruta\ejecucion_prueba.bat"
exit
This code does not work as expected. The output on execution is:
INFO: No tasks are running which match the specified criteria.
= was unexpected at this time.
What is wrong and how to do the batch file execution check correct?
tasklist.exe does not write to stdErr or record an ErrorLevel you can use, to determine whether the filters returned a task. In order to determine that, you need to use find.exe or findstr.exe to check for a known character or string in a successful output. You can then use the returned ErrorLevel or Success/Failure of that to validate instead.
The only 'relatively robust' way to perform this task using tasklist.exe is to first ensure that you initially ran your batch file, C:\ruta\ejecucion_prueba.bat using the following command:
Start "?" C:\ruta\ejecucion_prueba.bat
Or (recommended):
Start "?" "C:\ruta\ejecucion_prueba.bat"
With that done, you could run your verification batch file, with the following line in its content:
%SystemRoot%\System32\tasklist.exe /Fi "ImageName Eq cmd.exe" /Fi "Status Eq Running" /Fi "WindowTitle Eq ? - C:\ruta\ejecucion_prueba.bat" | %SystemRoot%\System32\find.exe "=" 1> NUL || Start "?" "C:\ruta\ejecucion_prueba.bat"
However, if your batch file path contains spaces:
C:\ruta\ejecucion prueba.bat
You'd need to have initially ran it using:
Start "?" "C:\ruta\ejecucion prueba.bat"
Then change the command in your batch script to:
%SystemRoot%\System32\tasklist.exe /Fi "ImageName Eq cmd.exe" /Fi "Status Eq Running" /Fi "WindowTitle Eq ? - \"C:\ruta\ejecucion prueba.bat\"" | %SystemRoot%\System32\find.exe "=" 1> NUL || Start "?" "C:\ruta\ejecucion prueba.bat"
Note: Regarding your previous intention to run this indefinitely, (which I do not recommend). When you start your .bat file, the Window Title, does not immediately register within tasklist.exe. That means, were you to run this in a loop or through a scheduled task, it is possible that the delay may cause your script to believe that the batch file isn't running, when in fact it is.
I essentially want to write a script that can help a program restart itself if becomes 'not responding'. I then want to log this to a simple text file with the time so that I can check later how often it needed to restart, but how do I properly check the status and store that in a variable for the script to then decide whether to restart it or ignore it (as its otherwise either not running or running fine)?
I found that I can do something like.....
taskkill /im "myProgram.exe" /fi "STATUS eq NOT RESPONDING" /f >nul && start "" "C:\Program Files (x86)\myProgram\myProgram.exe"
which I got from Batch file to kill and restart not responding program
This is great and gets me part way there but when I append something to write to a log, I find it seems to write to the log anyway rather than only if the status is 'not responding'. It also doesn't offer me much flexibility to handle it in an if/else statement if I want to do something else with it.
This is what I tried with the appended bit....
taskkill /im "myProgram.exe" /fi "STATUS eq NOT RESPONDING" /f >nul && SET message=%time% %date% - myProgram is was not running so restarted it && ECHO %message% >> myProgram_restart_LOG.txt && START "" "C:\Program Files (x86)\myProgram\myProgram.exe"
(I guessed that && isn't conditional on the previous statement in the chain being successful but executes anyway regardless?)
&& is conditional. The problem is that you are setting a variable and trying to access it directly. so either do call echo to access the variabe:
taskkill /im "myProgram.exe" /fi "STATUS eq NOT RESPONDING" /f >nul && SET message=%time% %date% - myProgram is was not running so restarted it && call ECHO %message% >> myProgram_restart_LOG.txt & START "" "C:\Program Files (x86)\myProgram\myProgram.exe"
Alternatively, just echo the message directly to the log file.
taskkill /im "myProgram.exe" /fi "STATUS eq NOT RESPONDING" /f >nul && SET echo %time% %date% - myProgram is was not running so restarted it >> myProgram_restart_LOG.txt & START "" "C:\Program Files (x86)\myProgram\myProgram.exe"
But I am not sure why you want to chain inside of a batch file, so I would do:
taskkill /im "myProgram.exe" /fi "STATUS eq NOT RESPONDING" /f >nul
if errorlevel 0 (
echo %time% %date% - myProgram is was not running so restarted it>> myProgram_restart_LOG.txt
START "" "C:\Program Files (x86)\myProgram\myProgram.exe"
)
I'm working on a batch file that is supposed to START a process (CMD) and then it should kill the process after finished. Problem is, that Imagename is cmd.exe and the other problem is that it should be running on Jenkins.
This is what I have tested:
Getting PID with wmic using name of window to find process -> Failed at Jenkins
Taskkill by naming the window-> Failed because Jenkins does not
display windows due to security issues.
Taskkill by imagename -> Failed because there are other cmd processes
running at the same time
Taskkill with pid but pid from the last cmd started. -Works but it is
not very safe.
I couldnĀ“t understand how wmic works but as I see, I cannot start a process with a command like with START command.
Conditions:
It can't be kill after some time because I need the output from the
mergetool and sometimes mergetool can take too long.
It should run at same time with other (cmd) processes // Jenkins
My question, is there a way of getting the PID from the START Command?
Here are some questions that helped me a lot!
Windows batch file : PID of last process?
Compare number of a specific process to a number
CODE:
set "console_name=cmd.exe"
set "git_command=%gitcmd% mergetool ^>output.txt"
tasklist /FI "imagename eq %console_name%" /NH /FO csv > task-before.txt
START "mergetool_w" CMD /c %git_command%
tasklist /FI "imagename eq %console_name%" /NH /FO csv > task-after.txt
for /f "delims=, tokens=2,*" %%A in ('fc /L /LB1 task-before.txt task-after.txt') do set pid=%%A
pid=!pid:"=!
echo pid is %pid%
TASKKILL /t /pid %pid% /f
You could actually use findstr for checking what tasks have been added after your start command line, relying on your files task-before.txt and task-after.txt:
findstr /LXVG:task-before.txt task-after.txt
Due to a nasty bug, this might under some circumstances lead to an unexpected output. To prevent that, add the /I option, if you can live with case-insensitive searches:
findstr /ILXVG:task-before.txt task-after.txt
Yes it's very possible. I'm going to take code from my previous awnser on another post here: Stop Execution of Batch File after 20 Seconds and move to Next
I want to first assume "mergetool_w" is the name of the CMD you are opining with the start...
The way you want to go about this is to search the tasklist for your console title and extract the PID# out of the context. The find suffix can be used to "Filter" the results along with tokens=2 to extract only the PID#.
FOR /F "tokens=2" %%# in ('tasklist /v ^| find "mergetool_w"') do set PID=%%#
From there, you can now kill this new window using the taskkill /pid command. The PID# is stored in the string %PID% so the command is simple:
taskkill /pid %PID% /t /f
Finaly, it looks as if you are trying to "Log" the data so feel free to put > text-task.txt where it's needed.
Have prepared a batch script to automate the build process. Was successfully able to figure out the success and failures of build using ant in batch script (%ERRORLEVEL%), accordingly displayed the message box with proper message.
Based on ant success have executed command to startup tomcat server, but how do i come to know in batch script whether it has been started or failed?
Your help is highly appreciated.!!
Thanks.
#echo off
call :is_running svchost.exe
echo %errorlevel%
call :is_running explorer.exe
echo %errorlevel%
call :is_running tomcat.exe
echo %errorlevel%
exit /b
:is_running
tasklist^
/fi "IMAGENAME eq %~1"^
/fi "STATUS eq running"^
/nh 2>nul | find "%~1" >nul || exit /b 1
exit /b 0
This calls a label named is_running and runs tasklist to find the ImageName running. If not running then errorlevel 1 is set. Added a few processes to test to display if it is working well.
Use the command tasklist /? for help.
I'm currently looking for the best way to manage a service start/stop under windows.
I will use the task sheduler provided by windows to start a script at a specific time.
The goal of the script is to :
check if the process "X" is running
if not service Y can be started
if yes, check in one hour if the process "X" is still running
And also what is the best language to do it ? Is Python a good choice ?
Sebastien
Here is a batch script (save as .bat)
tasklist /nh /fi "imagename eq x.exe" | find /i "x.exe" >nul && goto :HOURCHECK || net start Y
exit >nul
:HOURCHECK
timeout /t 3600
tasklist /nh /fi "imagename eq x.exe" | find /i "x.exe" >nul && REM Running || REM Not Running
Just replace my REM comments to do what you want when it checks after an hour.