Tempo rimasto prima dello spegnimento programmato?


8

Esiste un modo per visualizzare quanto tempo rimane prima di un arresto programmato in Windows 7?

Per arresto programmato intendo un arresto (o riavvio) pianificato utilizzando l' shutdown.exeapplicazione da riga di comando , ad esempio:

shutdown /t 600 /s

Ciò farebbe apparire una finestra di messaggio che dice che mancano 10 minuti allo spegnimento e l'ora di spegnimento effettiva del sistema.

In qualsiasi momento più lungo dei 600secondi utilizza invece un messaggio a fumetto.

Ricordo vagamente XP che fornisce un monitor di avanzamento della GUI, con un conto alla rovescia.

Come hanno funzionato? Il tempo di spegnimento residuo o il tempo programmato devono essere memorizzati da qualche parte, come posso accedervi?

La mia preferenza è un metodo attraverso la riga di comando (cioè non-GUI). Ancora più importante, è realizzabile in Windows, ovvero senza programmi di terze parti?

Se ciò non è realizzabile con i programmi di utilità standard di Windows (e qui sto confinando con il territorio Stack Overflow), esiste una funzione API di Windows (o .NET, che potrebbe persino essere utilizzata in PowerShell!)? O sarebbe preferito rispetto a qualche programma casuale di terze parti.


superuser.com/a/317062/117590 sembrava promettente, tuttavia, è preferibile / richiesto che il comando shutdown non venga modificato come l'aggiunta di un commento ( /c <time>).
Bob,

Penso che un file batch non sarebbe difficile da scrivere .. Richiedi il tempo, e ogni 5 minuti circa potrebbe rispondere con un tempo, cioè "10 minuti rimanenti" .. e quando arriva a 1, conto alla rovescia di secondi o qualcosa del genere.
cutrightjm

Non ho bisogno di un conto alla rovescia, ho bisogno di un metodo per ottenere il tempo rimanente in questo momento. Il comando shutdown viene chiamato da un programma esterno.
Bob

Risposte:


5

La domanda era interessante, quindi ho scritto un batch che può fare il lavoro per te.

Fondamentalmente è il conto alla rovescia, non ho incluso il shutdowncomando a questo ma l'ho lasciato a casa. I calcoli non sono accurati, questo non importa degli anni bisestili, della durata del mese, ... questo è principalmente per la leggibilità in quanto volevo che fosse facile da imparare.

Attualmente ci sono due file che fanno un lavoro insieme, uno avvia il timer e l'altro, quando chiamato, indica quanto tempo è trascorso dall'avvio del timer. Questi due file possono essere facilmente combinati in uno script cmd, in questo modo è possibile rendere riutilizzabili alcune righe ( come i metodi definiti ).

Ok, diamo un'occhiata agli script,

Ecco qui 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

In linea con FOR /F "skip=1 ...:
1. Richiedi wmicora e data attuali.
2. Salta la prima riga dell'output, ovvero i titoli, di skip=1
3. Leggi i valori usando il tokens=1-6significato %%a-%%fseparato da SpaceorTAB.
4. Memorizzare i valori alle variabili %DateY%, ... %TimeH%, %TimeM%...

Dopodiché all'inizio della riga SET /A EPOCH=...utilizziamo un'espressione che calcola i secondi trascorsi da1.1.1970 ( questo è un tempo approssimativo semplice, non reale di unix. Vedi Google se hai bisogno di precisione ).

Quindi all'ultima riga ECHO %EPOCH% > ...scrive il tempo calcolato nel file chiamato " Timer.start.state".

E qui 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

Qui il flusso del codice non è lineare dall'alto verso il basso. Prima di tutto GOTO CHECKFILEetichettiamo quindi i comandi di esecuzione iniziano davvero alla riga che dice :CHECKFILE. Molte cose qui sono esattamente le stesse di StartTimer.cmdcosì spiego solo linee nuove o modificate.

Per prima cosa controlliamo se Timer.start.stateesiste un file di stato , altrimenti non terminiamo il messaggio. Se il timer è stato avviato e i file esistono, continuiamo e facciamo un po 'di matematica:
1. Passa al punto in :TIMEOUTcui abbiamo emesso i secondi trascorsi. Puoi scegliere un'etichetta migliore per questo ...
2. SET /P %Timer% ... legge l'ora di inizio dal file e assegna il valore alla %Timer%variabile.
3. SET /A Elapsed ... calcola i secondi tra l'ora di inizio e ora.
4. ECHO "Seconds ... echeggia il valore calcolato (secondi dall'avvio del timer.

Come ottenere il tempo rimanente:

Puoi sottrarre %Elapsed%da %MaxTime%:

@ECHO OFF
GetTimerValue
SET /A TimeLeft=%MaxTime%-%Elapsed%
ECHO "You have %TimeLeft% seconds remaining"

OK, spiegato abbastanza. Ecco lo script completo Timer.cmd:

A questo punto, ho dimenticato tutto già detto. Questo file batch qui funziona da solo, quindi non esiste un separato StartTimer.cmdo GetTimerValue.cmdsolo questo Timer.cmd. Fondamentalmente è sempre lo stesso, ma il flusso di codice è diverso e anche l'utilizzo è completamente diverso. Questo, tuttavia, non salva lo stato nel file, quindi non è più possibile ottenere il valore del timer dopo la disconnessione / il riavvio, se è necessario questo esempio di cui sopra per salvare / leggere lo stato nel / dal file.

L'uso / aiuto per Timer.cmdviene stampato quando eseguito senza argomenti. Non l'ho ancora testato completamente e potrebbero esserci alcuni errori di battitura, ecc., Args non sono controllati a prova di errore.

@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

Integrazione con shutdowno qualsiasi altro comando:

File poweroff.cmd:

@ECHO OFF
Timer start %1
shutdown -t %1 -s

Utilizzo: poweroff <wait_seconds>per avviare lo spegnimento temporizzato e Timer getper ottenere il tempo trascorso / rimanente.


Ti applaudo per lo sforzo. Mi sono appena reso conto di quanto fosse formalmente formulata la domanda, ma sei comunque riuscito a rispondere. Solo per questo ottieni un voto. Sfortunatamente, questo non funziona con i comandi di spegnimento arbitrari, cioè StartTimer.cmddeve essere esplicitamente chiamato. Avevo scritto un piccolo programma per risolvere il mio problema, che posterò quando torno sul mio computer.
Bob,

Ok, accetterò questo. Ho finito per scrivere un programma C # che è stato chiamato shutdown.exe, che ha chiamato shutdown_original.exe. Verificherebbe la /tbandiera e se esistesse, creerebbe un file con i tempi di inizio e fine salvati. Durante il recupero dei tempi ( /retrieveflag), verificherebbe il registro eventi per vedere se è stato eseguito un avvio o l'interruzione dall'inizio del timer. Non sono sicuro di come avrebbe gestito l'ibernazione. Non pubblicherò il codice o il programma: è un disastro. E per far funzionare il programma, ho dovuto fare molto casino con le impostazioni di sicurezza, che non voglio promuovere.
Bob,

Il concetto di base era intercettare la shutdown.exechiamata e registrare i tempi in un file, che era quello che hai fatto e perché lo accetto.
Bob,

2
@Bob - Avresti pubblicato sul tuo programma quando sei tornato? Link al codice exe / source?
Alex S
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.