问题
I have a X.exe
program that takes about 2-6 hours to finish. Exact time is unknown, but I'd like to implement a threshold of 6.5 or 7 hours. If this program does not return any value by this amount of time, it will be killed. How do I implement this using batch *.bat
files?
Here is what I had so far: a timer bat1.bat
and an actual bat2.bat
.
bat1.bat:
start cmd /C bat2.bat & timeout /t 25200 & taskkill /im X.exe /f
bat2.bat:
cd blah
bat1.bat
The problem with this approach is that only after 25200 seconds (or 7 hours) the timer will be stopped, and it won't be terminated before that limit. How do I tell the computer that if the program X.exe
is finished then don't wait anymore?
Any help is appreciated!
回答1:
I think this is a much simpler solution:
rem Start the process that will kill the X.exe program after 7 hours
start "WaitingToKill" cmd /C timeout /t 25200 ^& taskkill /im X.exe /f
rem Run the X.exe program and wait for it to terminate
X.exe
rem Kill the killer process and terminate
taskkill /fi "WINDOWTITLE eq WaitingToKill" /f
In this method there is not any additional code running at same time; just the waiting state of timeout
command.
EDIT: Some explanations added
Note that both the "WaitingToKill" cmd.exe process with the timeout
command and the X.exe
program are running in parallel. If the timeout
command ends after 7 hours, the taskkill /im X.exe /f
command is executed, the X.exe
program is killed and both cmd.exe processes ends.
If the X.exe
program ends before the 7 hours, the Batch file execute the next line as usual. This line is taskkill /fi "WINDOWTITLE eq WaitingToKill" /f
, so the window with the timeout
command is killed and both cmd.exe processes ends.
回答2:
thanks to @Squashman i was able to build a script on my own. seem to work fine
@echo off
setlocal enableextensions enabledelayedexpansion
set /a "checktime=60"
set /a "elapsedtime=0"
set /a "killtime=150"
set XProg=X.exe
start cmd /C runTest.bat
timeout /t 10
:while1
echo Go to WHILE loop.
echo elapsedtime = %elapsedtime%
echo killtime = %killtime%
set /a "timeleft = %killtime% - %elapsedtime%"
echo timeleft = %timeleft%
if /i %timeleft% geq 0 (
tasklist /fi "imagename eq %XProg%" 2>NUL | find /i /n "%XProg%">NUL
if "%ERRORLEVEL%"=="0" (
echo %XProg% is still running...
) else (
echo %XProg% is finished before timer.
)
set /a "elapsedtime = elapsedtime + checktime"
timeout /t %checktime%
goto :while1
) else (
taskkill /im %XProg% /f
echo %XProg% is terminated.
)
lessons learned:
1. hard to compare numeric variables in batch (compare diff with 0 instead)
2. terminated first time elaspedtime > killtime
(might be a bit longer than killtime
depending how often it checks)
回答3:
I've tried various solutions but in the end this is really cumbersome in batch. If you are willing to use an external tool the simplest way is
"C:\Program Files\Git\usr\bin\timeout.exe" 5 .\test.exe
It properly returns the exit code of the test process, also works if you spawn multiple test processes simultaneously and does not pop up windows all the time.
来源:https://stackoverflow.com/questions/46858942/timeout-or-close-when-process-is-finished