setlocal EnableExtensions DisableDelayedExpansion
rem ===========================================================================
rem killtimer.bat -- run a command under a hard time limit (pure batch)
rem Interface contract (syntax, limits, exit codes): see :usage, or run /?.
rem
rem Mechanism: no PID needed. Child runs in its own minimized console with a
rem unique window title; poll tasklist once per second; on expiry, taskkill
rem by WINDOWTITLE filter (/t = whole process tree).
rem ===========================================================================
if /i "%~1"=="/?" goto :usage
if "%~1"=="" goto :usage
if "%~2"=="" goto :usage
if not "%~3"=="" goto :usage
set "KT_SEC=%~1"
set "KT_CMD=%~2"
rem --- validate <seconds>: digits only, 1..999999 ---------------------------
set "KT_CHK=%KT_SEC%"
for %%D in (0 1 2 3 4 5 6 7 8 9) do if defined KT_CHK call set "KT_CHK=%%KT_CHK:%%D=%%"
if defined KT_CHK goto :usage
if not "%KT_SEC:~6%"=="" goto :usage
if %KT_SEC% EQU 0 goto :usage
rem --- unique, filterable window title --------------------------------------
set "KT_TITLE=killtimer_%RANDOM%_%RANDOM%"
start "%KT_TITLE%" /min cmd /d /c "%KT_CMD%"
set /a "KT_ELAPSED=0"
:wait
rem ping = 1s delay; timeout.exe breaks under redirected stdin
ping -n 2 127.0.0.1 >nul
tasklist /fi "WINDOWTITLE eq %KT_TITLE%*" 2>nul | find /i "cmd.exe" >nul || exit /b 0
set /a "KT_ELAPSED+=1"
if %KT_ELAPSED% LSS %KT_SEC% goto :wait
taskkill /fi "WINDOWTITLE eq %KT_TITLE%*" /t /f >nul 2>&1
exit /b 124
:usage
echo(Usage: %~n0 ^<seconds^> "command"
echo(
echo( Runs "command" in its own window; if still running after ^<seconds^>
echo( seconds ^(1-999999^), force-kills it and all child processes.
echo(
echo( Exit codes: 0 done, 124 killed on timeout, 2 bad usage.
exit /b 2