Noch verbleibende Zeit vor dem geplanten Herunterfahren?

8

Gibt es eine Möglichkeit, anzuzeigen, wie viel Zeit noch vor einem geplanten Herunterfahren in Windows 7 verbleibt?

Mit geplantem Herunterfahren meine ich ein Herunterfahren (oder Neustarten), das mit der Befehlszeilenanwendung geplant wurde shutdown.exe, z.

shutdown /t 600 /s

Daraufhin wird ein Meldungsfeld angezeigt, in dem angegeben ist, dass bis zum Herunterfahren noch 10 Minuten und die tatsächliche Systemzeit für das Herunterfahren verbleiben.

Jeder Zeitpunkt, der länger als 600Sekunden dauert, verwendet stattdessen eine Sprechblasenmeldung.

Ich erinnere mich vage an XP, das einen GUI-Fortschrittsmonitor mit Countdown bereitstellt.

Wie haben sie gearbeitet? Die verbleibende oder geplante Abschaltzeit muss irgendwo gespeichert werden. Wie kann ich darauf zugreifen?

Ich bevorzuge eine Methode über die Befehlszeile (dh keine GUI). Noch wichtiger ist, ist dies unter Windows möglich, dh ohne Programme von Drittanbietern?

Wenn dies mit Standard-Windows-Dienstprogrammen nicht möglich ist (und ich hier an das Gebiet des Stapelüberlaufs grenzt), gibt es eine Windows-API (oder .NET, die sogar in PowerShell verwendet werden kann!)? Beides wäre einem zufälligen Programm eines Drittanbieters vorzuziehen.

Bob
quelle
superuser.com/a/317062/117590 sah vielversprechend aus, es wird jedoch bevorzugt / erforderlich, dass der Befehl zum Herunterfahren nicht wie beim Hinzufügen eines Kommentars ( /c <time>) geändert wird.
Bob
Ich denke, eine Batch-Datei wäre nicht schwer zu schreiben. Aufforderung zur Eingabe der Zeit, und alle 5 Minuten oder so könnte sie mit einer Zeit antworten, dh "10 Minuten verbleiben". Wenn sie 1 wird, zählen Sie bis herunter Sekunden oder so.
Cutrightjm
Ich brauche keinen Countdown, ich brauche eine Methode, um die verbleibende Zeit in diesem Moment zu ermitteln. Der Befehl zum Herunterfahren wird von einem externen Programm aufgerufen.
Bob

Antworten:

5

Die Frage war interessant, also habe ich einen Stapel geschrieben , der für Sie arbeiten kann.

Im Grunde ist es ein Countdown-Timer, ich habe keinen shutdownBefehl dazu eingefügt, sondern ihn als Hausaufgabe belassen. Berechnungen sind nicht genau, es geht nicht um Schaltjahre, Monatslänge, ... dies dient hauptsächlich der Lesbarkeit, da ich es einfach erlernen wollte.

Derzeit arbeiten zwei Dateien zusammen. Eine startet den Timer und die andere gibt beim Aufrufen an, wie viel Zeit seit dem Start des Timers vergangen ist. Diese beiden Dateien können ziemlich einfach zu einem Cmd-Skript kombiniert werden. Auf diese Weise können Sie auch einige Zeilen wiederverwendbar machen ( wie definierte Methoden ).

Okay, schauen wir uns die Skripte an.

Hier ist 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 Übereinstimmung mit FOR /F "skip=1 ...:
1. Fragen Sie wmicnach der aktuellen Uhrzeit und dem aktuellen Datum.
2. Zur ersten Zeile der Ausgabe, die Überschriften ist durch skip=1
3. Lesen Sie Werte mit tokens=1-6Bedeutungs %%a-%%fdurch getrennt SpaceorTAB.
4. Speichern Sie die Werte für Variablen %DateY%, ... %TimeH%, %TimeM%, ...

Danach verwenden SET /A EPOCH=...wir beim Zeilenanfang einen Ausdruck, der die verstrichenen Sekunden1.1.1970 berechnet ( dies ist eine einfache ungefähre, keine echte Unix-Zeit. Siehe Google, wenn Sie genaue Informationen benötigen ).

Dann ECHO %EPOCH% > ...schreibt in der letzten Zeile die berechnete Zeit in die Datei " Timer.start.state".

Und hier 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

Hier ist der Codefluss von oben nach unten nicht linear. Zuerst GOTO CHECKFILEbeschriften wir, damit Ausführungsbefehle wirklich in der Zeile beginnen, in der steht :CHECKFILE. Viele Dinge hier sind genauso wie bei, StartTimer.cmddeshalb erkläre ich nur neue oder geänderte Zeilen.

Zuerst prüfen wir, ob eine Statusdatei Timer.start.statevorhanden ist. Wenn nicht, beenden wir die Nachricht. Wenn der Timer gestartet wurde und Dateien vorhanden sind, fahren wir fort und rechnen nach:
1. Springen Sie zu der Stelle, :TIMEOUTan der wir die verstrichenen Sekunden ausgegeben haben. Sie können dafür eine bessere Bezeichnung wählen ...
2. SET /P %Timer% ... Liest die Startzeit aus der Datei und weist der %Timer%Variablen einen Wert zu .
3. SET /A Elapsed ... berechnet Sekunden zwischen Startzeit und jetzt.
4. gibt ECHO "Seconds ... den berechneten Wert wieder (Sekunden seit dem Start des Timers).

So erhalten Sie die verbleibende Zeit:

Sie können subtrahieren %Elapsed%von %MaxTime%:

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

OK, genug erklärt. Hier ist das vollständige Skript Timer.cmd:

Zu diesem Zeitpunkt habe ich alles vergessen, was bereits gesagt wurde. Diese Batch-Datei hier arbeitet alleine, es gibt also keine separate StartTimer.cmdoder GetTimerValue.cmdnur diese Timer.cmd. Grundsätzlich ist es immer noch dasselbe, aber der Codefluss ist unterschiedlich und die Verwendung ist auch völlig anders. Dies speichert den Status jedoch nicht in einer Datei, sodass Sie nach dem Abmelden / Neustarten keinen Timer-Wert mehr erhalten können. Wenn Sie dieses Beispiel oben benötigen, um den Status in einer Datei zu speichern / lesen.

Verwendung / Hilfe für Timer.cmdwird gedruckt, wenn sie ohne Argumente ausgeführt wird. Ich habe dies nicht vollständig getestet und es kann einige Tippfehler usw. geben, Argumente sind nicht narrensicher geprüft.

@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

Integrieren mit shutdownoder einem anderen Befehl:

Datei poweroff.cmd:

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

Verwendung: poweroff <wait_seconds>um das zeitgesteuerte Herunterfahren zu starten und Timer getdie verstrichene / verbleibende Zeit zu erhalten.

Sampo Sarrala - codidact.org
quelle
Ich begrüße Sie für die Mühe. Ich habe gerade festgestellt, wie schlecht die Frage formuliert war, aber Sie haben es trotzdem geschafft, sie zu beantworten. Nur dafür bekommst du eine Gegenstimme. Leider funktioniert dies nicht mit beliebigen Abschaltbefehlen, dh StartTimer.cmdmuss explizit aufgerufen werden. Ich hatte ein kleines Programm geschrieben, um mein Problem zu lösen, das ich veröffentlichen werde, wenn ich wieder auf meinem Computer bin.
Bob
Ok, ich werde das akzeptieren. Am Ende schrieb ich ein C # -Programm mit dem Namen shutdown.exe, das aufgerufen wurde shutdown_original.exe. Es würde nach dem /tFlag suchen und, falls vorhanden, eine Datei mit gespeicherten Start- und Endzeiten erstellen. Beim Abrufen der Zeiten ( /retrieveFlag) wird das Ereignisprotokoll überprüft, um festzustellen, ob seit dem Start des Timers ein Start oder ein Abbruch durchgeführt wurde. Ich bin mir nicht sicher, wie es mit Winterschlaf umgegangen wäre. Ich werde den Code oder das Programm nicht veröffentlichen: Es ist ein fehlerhaftes Durcheinander. Und damit das Programm funktioniert, musste ich viel mit Sicherheitseinstellungen herumspielen, die ich nicht fördern möchte.
Bob
Das Grundkonzept bestand darin, den shutdown.exeAnruf abzufangen und die Zeiten in einer Datei zu protokollieren. Das haben Sie getan und warum ich das akzeptiere.
Bob
2
@ Bob - Du wolltest über dein Programm posten, als du zurückkamst? Links zu Exe / Quellcode?
Alex S