Batch: Taskkill timeout without waiting for timer

我怕爱的太早我们不能终老 提交于 2021-01-29 17:53:30

问题


I'm writing a batch script which runs a few programs. As each program finishes what it's doing it waits for either the user to close it out, moving on to the next, or being closed by taskkill after a timeout of so many seconds. If I consider the main script as MAIN, the program as TASK and the timer as KILLER. The MAIN starts the TASK and KILLER at (about) the same time. TASK does what it's supposed to and KILLER waits 600 seconds before killing TASK. However if TASK were closed by the user it should kill the KILLER and return to MAIN without user interaction. However using ping or timeout I still have to wait for the timer to expire before the batch will actually close. I would like not to have my desktop littered with command windows that'll do nothing. Is there any way around this?


回答1:


You can use something like this

@echo off
    setlocal enableextensions disabledelayedexpansion

    start "" task.exe
    call :timeoutProcess "task.exe" 300

    start "" task.exe 
    call :timeoutProcess "task.exe" 300

    exit /b

:timeoutProcess process timeout [leave]
    rem process = name of process to monitor
    rem timeout = timeout in seconds to wait for process to end
    rem leave   = 1 if process should not be killed on timeout
    for /l %%t in (1 1 %~2) do (
        timeout /t 1 >nul
        tasklist | find /i "%~1" >nul || exit /b 0
    )
    if not "%~3"=="1" taskkill /f /im "%~1" >nul 2>nul
    if %errorlevel% equ 128 ( exit /b 0 ) else ( exit /b 1 )

The timeout logic is moved to a subroutine that will wait until the process ends or the timeout is reached.




回答2:


Here's a vbs script.

It waits till a program exits, see's if it's notepad, then restarts notepad if it is. Change Win32_ProcessStopTrace to Win32_ProcessStartTrace for program starts, or Win32_ProcessTrace for all starts and stops.

Console scripts are started like so. GUI scripts just execute the script direct. GUI scripts are invisible.

cscript "c:\somefolder\script.vbs"

To wait in a script use wscript.sleep 600000 (milliseconds).

Set WshShell = WScript.CreateObject("WScript.Shell")
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2") 
Set objEvents = objWMIService.ExecNotificationQuery _
    ("SELECT * FROM Win32_ProcessStopTrace")

Do
    Set objReceivedEvent = objEvents.NextEvent
    wscript.echo objReceivedEvent.ProcessName
    If lcase(objReceivedEvent.ProcessName) = lcase("Notepad.exe") then 
        WScript.echo "Process exited with exit code " & objReceivedEvent.ExitStatus
        WshShell.Run "c:\Windows\notepad.exe", 1, false
    End If
Loop

And this is how to start an invisible command window.

Set WshShell = WScript.CreateObject("WScript.Shell")

WshShell.Run "cmd /k dir c:\windows\*.*", 0, false


来源:https://stackoverflow.com/questions/26553727/batch-taskkill-timeout-without-waiting-for-timer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!