进程完成时超时或关闭

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 也有效。