进程完成时超时或关闭
timeout or close when process is finished
我有一个 X.exe
程序大约需要 2-6 小时才能完成。确切时间未知,但我想实施 6.5 或 7 小时的阈值。如果这个程序在这段时间内没有 return 任何值,它将被杀死。我如何使用批处理 *.bat
文件来实现它?
这是我目前所拥有的:一个计时器 bat1.bat
和一个实际的 bat2.bat
。
bat1.bat:
start cmd /C bat2.bat & timeout /t 25200 & taskkill /im X.exe /f
bat2.bat:
cd blah
bat1.bat
这种方法的问题在于,只有在 25200 秒(或 7 小时)后,计时器才会停止,并且不会在该限制之前终止。我如何告诉计算机,如果程序 X.exe
已完成,那么不要再等待了?
感谢任何帮助!
感谢@Squashman,我能够自己构建脚本。似乎工作正常
@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.
)
经验教训:
1. 难以批量比较数值变量(将 diff 与 0 进行比较)
2. 第一次终止 elaspedtime > killtime
(可能比 killtime
长一点,具体取决于它检查的频率)
我认为这是一个更简单的解决方案:
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
该方法中没有同时添加任何代码运行;只是 timeout
命令的等待状态。
编辑:添加了一些解释
请注意,使用 timeout
命令的 "WaitingToKill" cmd.exe 进程和 X.exe
程序都是 运行 并行的。如果 timeout
命令在 7 小时后结束,则执行 taskkill /im X.exe /f
命令,X.exe
程序被终止,两个 cmd.exe 进程结束。
如果 X.exe
程序在 7 小时之前结束,批处理文件会照常执行下一行 。这一行是 taskkill /fi "WINDOWTITLE eq WaitingToKill" /f
,所以带有 timeout
命令的 window 被杀死,两个 cmd.exe 进程结束。
我尝试了各种解决方案,但最后这批处理真的很麻烦。
如果您愿意使用外部工具,最简单的方法是
"C:\Program Files\Git\usr\bin\timeout.exe" 5 .\test.exe
它正确地 returns 测试进程的退出代码,如果您同时生成多个测试进程并且不会一直弹出 windows 也有效。
我有一个 X.exe
程序大约需要 2-6 小时才能完成。确切时间未知,但我想实施 6.5 或 7 小时的阈值。如果这个程序在这段时间内没有 return 任何值,它将被杀死。我如何使用批处理 *.bat
文件来实现它?
这是我目前所拥有的:一个计时器 bat1.bat
和一个实际的 bat2.bat
。
bat1.bat:
start cmd /C bat2.bat & timeout /t 25200 & taskkill /im X.exe /f
bat2.bat:
cd blah
bat1.bat
这种方法的问题在于,只有在 25200 秒(或 7 小时)后,计时器才会停止,并且不会在该限制之前终止。我如何告诉计算机,如果程序 X.exe
已完成,那么不要再等待了?
感谢任何帮助!
感谢@Squashman,我能够自己构建脚本。似乎工作正常
@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.
)
经验教训:
1. 难以批量比较数值变量(将 diff 与 0 进行比较)
2. 第一次终止 elaspedtime > killtime
(可能比 killtime
长一点,具体取决于它检查的频率)
我认为这是一个更简单的解决方案:
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
该方法中没有同时添加任何代码运行;只是 timeout
命令的等待状态。
编辑:添加了一些解释
请注意,使用 timeout
命令的 "WaitingToKill" cmd.exe 进程和 X.exe
程序都是 运行 并行的。如果 timeout
命令在 7 小时后结束,则执行 taskkill /im X.exe /f
命令,X.exe
程序被终止,两个 cmd.exe 进程结束。
如果 X.exe
程序在 7 小时之前结束,批处理文件会照常执行下一行 。这一行是 taskkill /fi "WINDOWTITLE eq WaitingToKill" /f
,所以带有 timeout
命令的 window 被杀死,两个 cmd.exe 进程结束。
我尝试了各种解决方案,但最后这批处理真的很麻烦。 如果您愿意使用外部工具,最简单的方法是
"C:\Program Files\Git\usr\bin\timeout.exe" 5 .\test.exe
它正确地 returns 测试进程的退出代码,如果您同时生成多个测试进程并且不会一直弹出 windows 也有效。