Pytanie było interesujące, więc napisałem partię, która może zrobić dla ciebie robotę.
Zasadniczo jest to odliczanie do zera, nie shutdown
podałem tego polecenia, ale zostawiłem go jako zadanie domowe. Obliczenia nie są dokładne, nie obchodzi ich lata przestępne, długość miesiąca, ... dotyczy to głównie czytelności, ponieważ chciałem ułatwić naukę.
Obecnie dwa pliki wykonują zadanie razem, jeden uruchamia stoper, a drugi, gdy jest wywoływany, mówi, ile czasu upłynęło od uruchomienia timera. Te dwa pliki można dość łatwo połączyć w jeden skrypt cmd, dzięki czemu niektóre linie mogą być ponownie używane ( jak zdefiniowane metody ).
Dobra, spójrzmy na skrypty,
Oto StartTimer.cmd
:
@ECHO OFF
FOR /F "skip=1 tokens=1-6" %%a IN ('wmic Path Win32_Localtime GET year^,month^,day^,hour^,minute^,second /format:TABLE ^| findstr /r "."') DO (
SET DateD=%%a
SET TimeH=%%b
SET TimeM=%%c
SET DateM=%%d
SET TimeS=%%e
SET DateY=%%f
)
SET /A EPOCH=((%DateY%-1970)*365*24*60*60)+(%DateM%*30*24*60*60)+(%DateD%*24*60*60)+(%TimeH%*60*60)+(%TimeM%*60)+%TimeS%
ECHO %EPOCH% > Timer.start.state
Zgodnie z FOR /F "skip=1 ...
:
1. Zapytaj wmic
o aktualną godzinę i datę.
2. Pomiń pierwszy wiersz wyniku, którym są nagłówki, o skip=1
3. Odczytaj wartości, używając tokens=1-6
znaczenia %%a-%%f
oddzielonego przez Spaceor
TAB.
4. Wartości sklepu do zmiennych %DateY%
, ... %TimeH%
, %TimeM%
...
Następnie na początku linii SET /A EPOCH=...
używamy wyrażenia, które oblicza upływające sekundy1.1.1970
( jest to prosty przybliżony, a nie rzeczywisty czas uniksowy. Zobacz Google, jeśli potrzebujesz dokładności ).
Następnie w ostatniej linii ECHO %EPOCH% > ...
zapisuje obliczony czas do pliku o nazwie „ Timer.start.state
”.
A tutaj GetTimerValue.cmd
:
@ECHO OFF
GOTO CHECKFILE
:TIMEOUT
FOR /F "skip=1 tokens=1-6" %%a IN ('wmic Path Win32_Localtime GET year^,month^,day^,hour^,minute^,second /format:TABLE ^| findstr /r "."') DO (
SET DateD=%%a
SET TimeH=%%b
SET TimeM=%%c
SET DateM=%%d
SET TimeS=%%e
SET DateY=%%f
)
SET /P Timer=<"Timer.start.state"
SET /A EPOCH=((%DateY%-1970)*365*24*60*60)+(%DateM%*30*24*60*60)+(%DateD%*24*60*60)+(%TimeH%*60*60)+(%TimeM%*60)+%TimeS%
SET /A Elapsed=%EPOCH%-%Timer%
ECHO "Seconds since timer started: %Elapsed%"
GOTO EOF
:CHECKFILE
IF EXIST "Timer.start.state" (
GOTO TIMEOUT
) ELSE (
ECHO "Timer not started. Start timer by running Timer.cmd"
)
:EOF
Tutaj przepływ kodu nie jest liniowy od góry do dołu. Najpierw oznaczamy GOTO CHECKFILE
etykietę, aby komendy wykonania naprawdę zaczynały się od linii, która mówi :CHECKFILE
. Wiele rzeczy tutaj jest tak samo jak z, StartTimer.cmd
więc wyjaśniam tylko nowe lub zmienione linie.
Najpierw sprawdzamy, czy plik stanu Timer.start.state
istnieje, a jeśli nie, to zakończ komunikat wit. Jeśli timer się uruchomił i pliki istnieją, kontynuujemy i wykonujemy matematykę:
1. Przejdź do :TIMEOUT
miejsca, w którym wyprowadzamy upływające sekundy. Możesz wybrać lepszą etykietę do tego ...
2. SET /P %Timer% ...
czyta czas rozpoczęcia z pliku i przypisuje wartość do %Timer%
zmiennej.
3. SET /A Elapsed ...
oblicza sekundy między czasem rozpoczęcia a teraz.
4. ECHO "Seconds ...
generuje echo obliczonej wartości (sekundy od uruchomienia timera.
Jak uzyskać pozostały czas:
Możesz odjąć %Elapsed%
od %MaxTime%
:
@ECHO OFF
GetTimerValue
SET /A TimeLeft=%MaxTime%-%Elapsed%
ECHO "You have %TimeLeft% seconds remaining"
OK, wystarczająco wyjaśnione. Oto pełny skrypt Timer.cmd
:
W tym momencie zapomniałem o wszystkim, co już powiedziano. Ten plik wsadowy działa tutaj samodzielnie, więc nie ma osobnego StartTimer.cmd
lub GetTimerValue.cmd
tylko to Timer.cmd
. Zasadniczo jest nadal taki sam, ale przepływ kodu jest inny, a użycie jest również zupełnie inne. Nie powoduje to jednak zapisania stanu do pliku, więc nie można już uzyskać wartości timera po wylogowaniu / ponownym uruchomieniu, jeśli potrzebujesz tego przykładu użycia powyżej, aby zapisać / odczytać stan do / z pliku.
Użycie / pomoc dla Timer.cmd
jest drukowane po uruchomieniu bez argumentów. Nie przetestowałem tego w pełni i mogą występować literówki itp. Argumenty nie są niezawodne.
@ECHO OFF
GOTO TimerUser%1
:: ===================================
:: Operation is start, (re)start timer
:: ===================================
:TimerUserstart
ECHO %2 | FINDSTR /R "^[1-9]"
IF %ERRORLEVEL%==0 (
SET Timer.max=%2
GOTO TimerStart
) ELSE (
ECHO.
ECHO !! ERROR !!
ECHO You must specify maximum value.
ECHO ===============================
GOTO TimerUser
)
:: =============================================
:: Operation is get, get values if timer running
:: =============================================
:TimerUserget
IF DEFINED Timer.start.state (
GOTO TIMEOUT
) ELSE (
ECHO.
ECHO !! ERROR !!
ECHO Timer is not started, start timer first.
ECHO ========================================
GOTO TimerUser
)
:: ============
:: Usage / Help
:: ============
:TimerUser
ECHO.
ECHO Timer.cmd Usage: Timer.cmd operation [options]
ECHO.
ECHO - Operations
ECHO start Start new timer, n must be specified.
ECHO get Get current value of started timer.
ECHO.
ECHO - Options:
ECHO n Max value in seconds, used to calculate remaining time.
ECHO.
GOTO EOF
:: =============================
:: Update %Timer.epoch% variable
:: =============================
:TimerUpdateEpoch
FOR /F "skip=1 tokens=1-6" %%a IN ('wmic Path Win32_Localtime GET year^,month^,day^,hour^,minute^,second /format:TABLE ^| findstr /r "."') DO (
SET DateD=%%a
SET TimeH=%%b
SET TimeM=%%c
SET DateM=%%d
SET TimeS=%%e
SET DateY=%%f
)
SET /A Timer.epoch=((%DateY%-1970)*365*24*60*60)+(%DateM%*30*24*60*60)+(%DateD%*24*60*60)+(%TimeH%*60*60)+(%TimeM%*60)+%TimeS%
GOTO %Timer.Callback%
:: ===========================================
:: Start new timer destoying/resetting old one
:: ===========================================
:TimerStart
SET Timer.Callback=TimerStartC1
GOTO TimerUpdateEpoch
:TimerStartC1
SET Timer.start.state=%Timer.epoch%
GOTO EOF
:: =============================
:: Echo out current timer values
:: =============================
:TIMEOUT
SET Timer.Callback=TimerEchoJ1
GOTO TimerUpdateEpoch
:TimerEchoJ1
SET /A Timer.elapsed=%Timer.epoch%-%Timer.start.state%
SET /A Timer.remaining=%Timer.max%-%Timer.elapsed%
ECHO "Seconds since timer started: %Timer.elapsed% Time remaining %Timer.remaining%"
GOTO EOF
:EOF
Zintegruj z shutdown
dowolnym innym poleceniem:
Plik poweroff.cmd
:
@ECHO OFF
Timer start %1
shutdown -t %1 -s
Zastosowanie: poweroff <wait_seconds>
do rozpoczęcia czasowego wyłączenia i Timer get
do upływu czasu / pozostałego czasu.
/c <time>
robi to dodawanie komentarza ( ).