Last active
June 27, 2019 22:45
-
-
Save redneck-f25/5eaaa3c1e175102ddc984c753cdf0311 to your computer and use it in GitHub Desktop.
Respawn Windows Console Processes and collect std{out,err} (i.e. for startup-tasks)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off & setlocal enableextensions enabledelayedexpansion | |
if "%~1" == "" ( | |
set "conf_file=%~dpn0.conf.cmd" | |
) else ( | |
set "conf_file=%~dp0%~1.conf.cmd" | |
) | |
call "%conf_file%" || ( pause & exit 1 ) | |
goto __main__ | |
:log | |
echo [%DATE% %TIME: =0% %pid%]: %* | |
goto :eof | |
:__main__ | |
rem get pid | |
rem @see https://serverfault.com/questions/126502/how-to-get-own-process-pid-from-the-command-prompt-in-windows/654029#654029 | |
set "uniq=%~f0:%DATE%-%TIME: =0%-%RANDOM%-%RANDOM%" & set "uniq=!uniq:#=#0!" & set "uniq=!uniq::=#1!" & set "uniq=!uniq:,=#2!" & set "uniq=!uniq:/=#3!" & set "uniq=!uniq:\=#4!" & set "uniq=!uniq:`=#5!" | |
set "lock=%TEMP%\%uniq%.lock" | |
2>nul ( 4>"%lock%" ( | |
for /f "usebackq skip=1 tokens=1,2" %%a in ( | |
`wmic process where ^( Name^="cmd.exe" and CommandLine like "%%<%uniq%>%%" ^) get ParentProcessId` | |
) do for %%b in (%%a) do set pid=%%b | |
)) || goto __main__ | |
del "%lock%" 2>nul | |
>>"%LOGFILE%.%pid%.tmp" call :log +++ start %~f0 %conf_file% | |
rem try to terminate other instance of this respawn script and the target program | |
for /f "usebackq tokens=1" %%a in ( `type "%PIDFILE%" 2^>nul` ) do ( | |
set /a "pcmdpid=%%a+0" | |
if "!pcmdpid!" neq "0" ( | |
for /f "usebackq skip=1 tokens=1" %%b in ( `wmic process where ^( Name^="cmd.exe" and ParentProcessId^="%%a" ^) get ProcessId 2^>nul` ) do ( | |
set /a "cmdpid=%%b+0" | |
if "!cmdpid!" neq "0" ( | |
for /f "usebackq skip=1 tokens=1" %%c in ( `wmic process where ^( ExecutablePath^="%PROGRAM:\=\\%" and ParentProcessId^="%%b" ^) get ProcessId 2^>nul` ) do ( | |
set /a "programpid=%%c+0" | |
if "!programpid!" neq "0" ( | |
>>"%LOGFILE%.%pid%.tmp" call :log Terminate running instance (!pcmdpid!,!programpid!) | |
rem delete the run-file as signal for the respawn-loop below | |
del "%RUNFILE%" 2>nul | |
>>"%LOGFILE%.%pid%.tmp" 2>&1 wmic process where ^( ExecutablePath="%PROGRAM:\=\\%" and ProcessId="!programpid!" ^) call terminate | |
rem give some time to release the logfile | |
timeout /t 1 /nobreak >nul | |
) | |
) | |
) | |
) | |
) | |
) | |
rem terminate other target programs inclusive two cmd-parents (missing pidfile) | |
for /f "usebackq skip=1 tokens=1,2" %%a in ( `wmic process where ExecutablePath^="%PROGRAM:\=\\%" get ParentProcessId^,ProcessId 2^>nul` ) do ( | |
set /a "otherprogrampid=%%b+0" | |
if "!otherprogrampid!" neq "0" ( | |
set "cond=ProcessID="!otherprogrampid!"" | |
for /f "usebackq skip=1 tokens=1,2" %%c in ( `wmic process where ^( ProcessId^="%%a" and Name^="cmd.exe" ^) get ParentProcessId^,ProcessId 2^>nul` ) do ( | |
set /a "othercmdpid=%%d+0" | |
if "!othercmdpid!" neq "0" ( | |
set "cond=!cond! or ProcessID="!othercmdpid!"" | |
for /f "usebackq skip=1 tokens=1" %%e in ( `wmic process where ^( ProcessId^="%%c" and Name^="cmd.exe" ^) get ProcessId 2^>nul` ) do ( | |
set /a "otherpcmdpid=%%e+0" | |
if "!otherpcmdpid!" neq "0" ( | |
set "cond=!cond! or ProcessID="!otherpcmdpid!"" | |
) | |
) | |
) | |
) | |
>>"%LOGFILE%.%pid%.tmp" call :log Terminate running instances (!otherpcmdpid!,!otherprogrampid!) | |
>>"%LOGFILE%.%pid%.tmp" 2>&1 wmic process where ^( !cond! ^) call terminate | |
) | |
) | |
>"%RUNFILE%" <nul set /p "_=" | |
rem fails if log-file is still open (other user context, missing permissins) | |
type "%LOGFILE%.%pid%.tmp" >>"%LOGFILE%" || ( pause & exit 1 ) | |
del "%LOGFILE%.%pid%.tmp" | |
>"%PIDFILE%" echo\%pid% | |
:loop | |
>>"%LOGFILE%" call :log spawn "%PROGRAM%" %ARGS% | |
start "" /wait cmd /c ""%PROGRAM%" %ARGS% >>"%LOGFILE%" 2>&1" | |
>>"%LOGFILE%" call :log terminated with exitcode %ERRORLEVEL% | |
rem if pid-file exists and still contains current pid, respawn after timeout | |
if exist "%RUNFILE%" ( | |
for /f "usebackq" %%a in ( `type "%PIDFILE%" 2^>nul` ) do ( | |
if "%%a" == "%pid%" ( | |
timeout /t %RESPAWN_DELAY% /nobreak >nul | |
goto loop | |
) | |
) | |
) | |
del "%PIDFILE%" 2>nul | |
>>"%LOGFILE%" call :log === exit %~f0 %conf_file% |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off & setlocal enableextensions enabledelayedexpansion | |
if "%~1" == "" ( | |
set "conf_file=%~dp0respawn.conf.cmd" | |
) else ( | |
set "conf_file=%~dp0respawn-%~1.conf.cmd" | |
) | |
call "%conf_file%" || ( pause & exit 1 ) | |
for /f "usebackq tokens=1" %%a in ( `type "%PIDFILE%" 2^>nul` ) do ( | |
set /a "pcmdpid=%%a+0" | |
if "!pcmdpid!" neq "0" ( | |
for /f "usebackq skip=1 tokens=1" %%b in ( `wmic process where ^( Name^="cmd.exe" and ParentProcessId^="%%a" ^) get ProcessId` ) do ( | |
set /a "cmdpid=%%b+0" | |
if "!cmdpid!" neq "0" ( | |
for /f "usebackq skip=1 tokens=1" %%c in ( `wmic process where ^( ExecutablePath^="%PROGRAM:\=\\%" and ParentProcessId^="%%b" ^) get ProcessId` ) do ( | |
set /a "programpid=%%c+0" | |
if "!programpid!" neq "0" ( | |
del "%RUNFILE%" | |
wmic process where ^( ExecutablePath="%PROGRAM:\=\\%" and ProcessId="!programpid!" ^) call terminate | |
) | |
) | |
) | |
) | |
) | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@"%~dp0_respawn.cmd" "%~n0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
set "PROGRAM=C:\Windows\system32\PING.EXE" | |
set "ARGS=-t localhost" | |
set "LOGFILE=%~dp0respawn-ping.log" | |
set "PIDFILE=%~dp0respawn-ping.pid" | |
set "RUNFILE=%~dp0respawn-ping.run" | |
set "RESPAWN_DELAY=5" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@"%~dp0_terminate.cmd" "ping" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment