Tempo restante antes do encerramento programado?

8

Existe alguma maneira de ver quanto tempo resta antes de um desligamento programado no Windows 7?

Por desligamento programado, quero dizer, um desligamento (ou reinício) agendado usando a linha de comando shutdown.exe application, por exemplo:

shutdown /t 600 /s

Isso abriria uma caixa de mensagem dizendo que há 10 minutos até o desligamento e a hora real de desligamento do sistema.

Qualquer tempo maior que 600 segundos usa uma mensagem em balão.

Eu me lembro vagamente do XP fornecendo um monitor de progresso da GUI, com uma contagem regressiva.

Como eles funcionam? O tempo de desligamento deixado ou o horário programado deve ser armazenado em algum lugar, como posso acessar isso?

Minha preferência é algum método através da linha de comando (ou seja, não-GUI). Mais importante, isso é realizável no Windows, ou seja, sem programas de terceiros?

Se isso não for possível com os utilitários padrão do Windows (e eu estou chegando ao limite do Stack Overflow aqui), existe uma função de API do Windows (ou .NET, que pode até mesmo ser usada no PowerShell!)? Qualquer um seria preferível a algum programa de terceiros aleatório.

    
por Bob 19.04.2012 / 13:11

1 resposta

5

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.

    
por 15.05.2012 / 00:02