Maksym Polshcha
Maksym Polshcha

Reputation: 18358

Windows batch: analogue for `timeout` command

I'm trying to find out how to limit a program execution time within a Windows batch file. Is there something like Unix timeout command? Please advise.

Upvotes: 3

Views: 6380

Answers (5)

Arty
Arty

Reputation: 590

To do this, you can use the BusyBox for Windows (https://frippery.org/busybox/ https://github.com/rmyorston/busybox-w32) with the command busybox timeout 10 yourprogram.exe.

Upvotes: 0

Maksym Polshcha
Maksym Polshcha

Reputation: 18358

I just installed Cygwin and use unix-style timeout command from the distribution.

Upvotes: 2

James K
James K

Reputation: 4055

This code waits 60 seconds, then checks to see if %ProgramName% is running.

To increase this time, change the value of WaitForMinutes.

To decrease the interval between checks, set WaitForSeconds for the number of seconds you want it to wait.

@echo off
set ProgramName=calc.exe
set EndInHours=2

:: How Many Minutes in between each check to see if %ProgramName% is Running
:: To change it to seconds, just set %WaitForSeconds% Manually
set WaitForMinutes=1
set /a WaitForSeconds=%WaitForMinutes%*60

:: How many times to loop
set /a MaxLoop=(%EndInHours%*60*60) / (%WaitForMinutes%*60)

REM Use a VBScript popup window asking to terminate %ProgramName%
echo set WshShell = WScript.CreateObject("WScript.Shell") > %tmp%\tmp.vbs
echo Wscript.Quit (WshShell.Popup( "Click 'OK' to terminate %ProgramName%." ,10 ,"Terminate %ProgramName%", 0)) >> %tmp%\tmp.vbs

start %ProgramName%
set running=True
:: Give time for %ProgramName% to launch.
timeout /t 5 /nobreak > nul
setlocal enabledelayedexpansion
for /l %%x in (1,1,%MaxLoop%) do (
  if "!running!"=="True" for /l %%y in (1,1,%WaitForMinutes%) do (
    if "!running!"=="True" (
      set running=False
      REM call Pop-Up
      cscript /nologo %tmp%\tmp.vbs
      if !errorlevel!==-1 (
        for /f "skip=3" %%x in ('tasklist /fi "IMAGENAME EQ %ProgramName%"') do set running=True
      ) else (
        taskkill /im %ProgramName%
      )
    )
  )
)
if exist %tmp%\tmp.vbs del %tmp%\tmp.vbs

This code uses VBScript to make a pop-up box. Clicking OK will cause %ProgramName% to be killed via taskkill.


If you do not want to use a pop-up window, you can use timeout by removing...

REM Use a VBScript popup window asking to terminate %ProgramName%
echo set WshShell = WScript.CreateObject("WScript.Shell") > %tmp%\tmp.vbs
echo Wscript.Quit (WshShell.Popup( "Click 'OK' to terminate %ProgramName%." ,10 ,"Terminate %ProgramName%", 0)) >> %tmp%\tmp.vbs

...and replacing this...

      REM call Pop-Up
      cscript /nologo %tmp%\tmp.vbs
      if !errorlevel!==-1 (

...with this:

      REM Use CTRL+C to kill %ProgramName%
      timeout /t %WaitForSeconds% /nobreak
      if !errorlevel!==0 (

Using /nobreak is necessary because timeout does not distinguish between pressing a key or timing out. This will allow you to terminate %ProgramName% by pressing CTRL+C , but that causes your batch file to ask Terminate batch job (Y/N)? when you do. Sloppy/Messy/Nasty IMHO.


You could instead use CHOICE by replacing the above mentioned code with this:

      REM Using choice, but choice can get stuck with a wrong keystroke
      Echo [K]ill %ProgramName% or [S]imulate %WaitForSeconds% Seconds
      Choice /n /c sk /t %WaitForSeconds% /d s
      if !errorlevel!==1 (

But choice brings it's own set of limitations to the table. For one thing, it will stop it's countdown if a key that is not among it's choices (in this case s and k) has been pressed, essentially locking up until a correct choice is made. Second, the SPACEBAR cannot be a choice.

Upvotes: 0

Bali C
Bali C

Reputation: 31231

To limit the time a program has to run you could do something like this

start yourprogram.exe
timeout /t 10
taskkill /im yourprogram.exe /f

That starts yourprogram.exe, waits 10 seconds, then kills the program.

Upvotes: 4

perreal
perreal

Reputation: 97958

I don't think there is a timeout command. However, you can start executing a task in the background and sleep (using ping) for the timeout duration then kill the task.

Upvotes: 0

Related Questions