Batch: Abbrechbarer Countdown, Timeout
Hallo Community,
wenn man sich das Topic so ansieht, könnte man sich die Frage stellen, wozu das Ganze? Es gibt doch bereits das TIMEOUT Befehlstool! Stimmt - wenn da nicht die von Biber ab und zu herangezogenen "Redmonder Praktikantinnen in Hängehöschen" wieder mal zu viele bunte Pillen eingeworfen hätten als sie den Code dafür zusammengeschrotet haben ...
Meine Anforderung: Gib einem User die Möglichkeit eine Aktion innerhalb einer bestimmten Zeitspanne abzubrechen.
Wer nun versucht TIMEOUT dafür zu verwenden, wird feststellen, dass das Ding prima einen Countdown ins Consolefenster zaubert. Das wars dann aber auch schon. Egal ob der Benutzer abbricht oder der Countdown abgelaufen ist, am Ende wird man weder in der Lage sein das Eine oder das Andere zu ermitteln. Errorlevel-Logik? Fehlanzeige! Der bleibt in jedem Fall 0.
Ich habe mal versucht eine Subroutine zu basteln, die aus der TIMEOUT-Ausgabe was Verwertbares macht. Dieser übergibt man 3 Parameter:
Im Beispiel:
Risiken und Nebenwirkungen?
Ja klar, ist ja lediglich ein Workaround. Das Ding kommt nicht ohne temporäre Datei aus, in die die Ausgabe von TIMEOUT erst mal gepuffert wird. Was heißt das?:
Grüße
rubberman
wenn man sich das Topic so ansieht, könnte man sich die Frage stellen, wozu das Ganze? Es gibt doch bereits das TIMEOUT Befehlstool! Stimmt - wenn da nicht die von Biber ab und zu herangezogenen "Redmonder Praktikantinnen in Hängehöschen" wieder mal zu viele bunte Pillen eingeworfen hätten als sie den Code dafür zusammengeschrotet haben ...
Meine Anforderung: Gib einem User die Möglichkeit eine Aktion innerhalb einer bestimmten Zeitspanne abzubrechen.
Wer nun versucht TIMEOUT dafür zu verwenden, wird feststellen, dass das Ding prima einen Countdown ins Consolefenster zaubert. Das wars dann aber auch schon. Egal ob der Benutzer abbricht oder der Countdown abgelaufen ist, am Ende wird man weder in der Lage sein das Eine oder das Andere zu ermitteln. Errorlevel-Logik? Fehlanzeige! Der bleibt in jedem Fall 0.
Ich habe mal versucht eine Subroutine zu basteln, die aus der TIMEOUT-Ausgabe was Verwertbares macht. Dieser übergibt man 3 Parameter:
- Die Wartezeit in Sekunden.
- Die Message, die während des Countdowns angezeigt werden soll. Diese kann ein Wildcardzeichen enthalten, das gegen den Coutdown ausgetauscht wird.
- Das Zeichen, das als Wildcard interpretiert werden soll.
Im Beispiel:
@echo off &setlocal
set /a "wait=10"
call :xtimeout %wait% "Timeout in # s, Abbruch mit beliebiger Taste." #
echo ERRORLEVEL: %errorlevel%
if errorlevel 1000 (echo Fehler) else if errorlevel 1 (echo Abgebrochen.) else echo %wait% Sekunden abgelaufen.
echo(
pause
goto :eof
:::::::::::::::::::::::::::::::::::
:xtimeout Zeit [Text] [Platzhalter]
call;&(if not defined __bs__ call)&&(if not defined __cr__ call)&&(if not defined __lf__ call)&if errorlevel 1 (
setlocal DisableDelayedExpansion
2>nul set /a "countdown = %~1, before = %~1 + 1"&set "txt=%~2 "&set "wildcard=%~3"
for /f %%i in ('"prompt;$h&for %%i in (1) do rem"') do set "__bs__=%%i" &REM ~BackSpace~
for /f %%a in ('copy /z "%~f0" nul') do set "__cr__=%%a" &REM ~CarriageReturn~
set __lf__=^
REM Zwei Leerzeilen sind erforderlich! ~LineFeed~
setlocal EnableDelayedExpansion
call;&(if !countdown! lss 1 call)&&(if !countdown! gtr 300 call)&if errorlevel 1 (endlocal&endlocal&exit /b 2147483647)
if not defined wildcard set "wildcard=!__bs__!"
set "file=!temp!\!random!-!random!.timeout"
start "" /b cmd /von /c ">"!file!" timeout /t !countdown!&>"!file!" echo 2147483647"
)
if not exist "!file!" goto xtimeout
for /f "delims=" %%i in ('type "!file!"') do set "countdown=%%i"
for /f "delims=" %%i in ('"call echo %%countdown:!__bs__!=^!__lf__^!%%"') do set "countdown=%%i"
for /f %%i in ("!countdown!") do set "countdown=%%i"
if %before% gtr %countdown% (
if defined txt <nul set /p "=%__bs__%!__cr__!!txt:%wildcard%=%countdown%!%__bs__%"
set /a "before = countdown"
goto xtimeout
) else (
if %countdown% equ 2147483647 (
del "!file!"
echo(
endlocal&endlocal&exit /b %before%
) else (
goto xtimeout
)
)
Risiken und Nebenwirkungen?
Ja klar, ist ja lediglich ein Workaround. Das Ding kommt nicht ohne temporäre Datei aus, in die die Ausgabe von TIMEOUT erst mal gepuffert wird. Was heißt das?:
- Zwei Prozesse schreiben und lesen gleichzeitig asynchron und benutzen dabei die gleiche Datei. Das kann auch mal in die Hose gehen.
- Die Ausgabe von TIMEOUT landet in einer einzigen Zeile, der Countdown wird dort mit Backspacezeichen immer wieder überschrieben. Irgendwann ist die Zeile zu lang um mit Batch einlesbar zu sein. Ich habe deshalb auf 300 Sekunden Maximum begrenzt. Das hat bei mir (Win7 x86 und x64) im Test immer funktioniert.
Grüße
rubberman
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 211742
Url: https://administrator.de/contentid/211742
Ausgedruckt am: 21.11.2024 um 20:11 Uhr
2 Kommentare
Neuester Kommentar