A pergunta foi interessante, então eu escrevi o lote que pode fazer o trabalho para você.
Basicamente é temporizador de contagem regressiva, eu não incluí o comando shutdown
para isso, mas deixei como lição de casa. Cálculos não são precisos, isso não se preocupa com anos bissextos, duração do mês, ... isso é principalmente para a legibilidade, pois eu queria que fosse fácil de aprender.
Atualmente há dois arquivos trabalhando juntos, um inicia o temporizador e outro, quando chamado, informa quanto tempo passou desde o início do temporizador. Esses dois arquivos podem ser facilmente combinados em um script cmd, dessa forma você pode tornar algumas linhas reutilizáveis ( como métodos definidos ) também.
Ok, vamos dar uma olhada nos scripts,
Aqui está o 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
Na linha que começa com FOR /F "skip=1 ...
:
1. Peça wmic
para a hora e a data atuais.
2. Pule a primeira linha da saída , que é títulos, por skip=1
3. Valores de leitura usando tokens=1-6
significando %%a-%%f
separados por Espaço or
TAB .
4. Armazena valores para as variáveis %DateY%
, ... %TimeH%
, %TimeM%
, ...
Depois disso, na linha que inicia SET /A EPOCH=...
, usamos a expressão que calcula segundos decorridos em 1.1.1970
( este é um tempo aproximativo simples, não real do unix. Veja o Google se você precisar de precisão ).
Então, na última linha, ECHO %EPOCH% > ...
escreve o tempo calculado para o arquivo chamado " Timer.start.state
".
E aqui 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
O fluxo de código aqui não é linear de cima para baixo. Primeiro nós GOTO CHECKFILE
label então os comandos de execução realmente começam na linha que diz :CHECKFILE
.
Muitas coisas aqui são as mesmas que com StartTimer.cmd
, então eu só explico linhas novas ou alteradas.
Primeiro, verificamos se o arquivo de estado Timer.start.state
existe, senão terminamos com a mensagem. Se o temporizador começou e os arquivos existem, então continuamos e fazemos algumas contas:
1. Salte para :TIMEOUT
, onde saímos os segundos decorridos. Você pode escolher um rótulo melhor para isso ...
2. SET /P %Timer% ...
lê a hora de início do arquivo e atribui valor à variável %Timer%
.
3. SET /A Elapsed ...
calcula os segundos entre a hora de início e agora.
4. ECHO "Seconds ...
ecoa o valor calculado (segundos desde a inicialização do temporizador.
Como obter tempo restante:
Você pode subtrair %Elapsed%
de %MaxTime%
:
@ECHO OFF
GetTimerValue
SET /A TimeLeft=%MaxTime%-%Elapsed%
ECHO "You have %TimeLeft% seconds remaining"
OK, explicou o suficiente. Aqui está o script completo Timer.cmd
:
Neste ponto, esqueci tudo o que já foi dito. Este arquivo de lote aqui está funcionando sozinho, portanto, não há StartTimer.cmd
ou GetTimerValue.cmd
separadas, mas somente Timer.cmd
. Basicamente, ainda é o mesmo, mas o fluxo de código é diferente e o uso também é completamente diferente. No entanto, isso não salva o estado para o arquivo, para que você não consiga mais obter o valor do timer após o logoff / reboot, se precisar deste exemplo de uso acima para salvar / ler o estado de / para o arquivo.
O uso / ajuda para Timer.cmd
é impresso quando executado sem argumentos. Eu não testei completamente isso e pode haver alguns erros de digitação etc., args não são verificados à prova de erros.
@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
Integre com shutdown
ou qualquer outro comando:
Arquivo poweroff.cmd
:
@ECHO OFF
Timer start %1
shutdown -t %1 -s
Uso: poweroff <wait_seconds>
para iniciar o desligamento cronometrado e Timer get
para passar o tempo restante.