Tiempo restante antes del cierre programado?


8

¿Hay alguna manera de ver cuánto tiempo queda antes de un apagado programado en Windows 7?

Por apagado programado me refiero a un apagado (o reinicio) programado usando la shutdown.exeaplicación de línea de comando , por ejemplo:

shutdown /t 600 /s

Aparecería un cuadro de mensaje que indica que faltan 10 minutos para el apagado y la hora real de apagado del sistema.

En cualquier momento más largo que 600segundos se usa un mensaje de globo en su lugar.

Recuerdo vagamente que XP proporcionaba un monitor de progreso de la GUI, con una cuenta regresiva.

¿Cómo funcionaron? El tiempo de apagado restante o el tiempo programado deben almacenarse en algún lugar, ¿cómo puedo acceder a esto?

Mi preferencia es algún método a través de la línea de comando (es decir, no GUI). Más importante aún, ¿esto se puede lograr en Windows, es decir, sin ningún programa de terceros?

Si esto no se puede lograr con las utilidades estándar de Windows (y estoy limitando con el territorio de Stack Overflow aquí), ¿hay una API de Windows (o .NET, que incluso podría usarse en PowerShell)? Cualquiera de los dos sería preferible a algún programa de terceros aleatorio.


superuser.com/a/317062/117590 parecía prometedor, sin embargo, se prefiere / requiere que el comando de apagado no se modifique como lo hace agregar un comentario ( /c <time>).
Bob

Creo que un archivo por lotes no sería difícil de escribir ... Preguntar por el tiempo, y cada 5 minutos más o menos podría responder con un tiempo, es decir, "10 minutos restantes" ... y cuando llegue a 1, haga la cuenta regresiva por segundos o algo
cutrightjm

No necesito una cuenta regresiva, necesito algún método para obtener el tiempo restante en este momento. El comando de apagado está siendo llamado por un programa externo.
Bob

Respuestas:


5

La pregunta era interesante, así que escribí un lote que puede hacer el trabajo por usted.

Básicamente es un temporizador de cuenta regresiva, no incluí el shutdowncomando para esto, pero lo dejé como tarea. Los cálculos no son precisos, esto no se preocupa por los años bisiestos, la duración del mes, ... esto es principalmente para facilitar la lectura, ya que quería que fuera fácil de aprender.

Actualmente hay dos archivos trabajando juntos, uno inicia el temporizador y el otro, cuando se llama, indica cuánto tiempo transcurrió desde el inicio del temporizador. Estos dos archivos se pueden combinar con bastante facilidad en un script de cmd, de esta manera también puede hacer que algunas líneas sean reutilizables ( como los métodos definidos ).

Bien, echemos un vistazo a los guiones,

Aqui esta 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

En línea comenzando con FOR /F "skip=1 ...:
1. Pregunte wmicpor la hora y fecha actuales.
2. Omita la primera línea de salida, que es encabezados, en skip=1
3. Lea los valores usando el tokens=1-6significado %%a-%%fseparado por SpaceorTAB.
4. Almacenar los valores de las variables %DateY%, ... %TimeH%, %TimeM%, ...

Después de eso, al comienzo de la línea SET /A EPOCH=..., usamos una expresión que calcula los segundos transcurridos desde1.1.1970 ( esto es simple aproximado, no un tiempo real de Unix. Vea Google si necesita información precisa ).

Luego, en la última línea ECHO %EPOCH% > ...escribe el tiempo calculado para el archivo llamado " Timer.start.state".

Y 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

Aquí el flujo de código no es lineal de arriba a abajo. Primero GOTO CHECKFILEetiquetamos para que los comandos de ejecución realmente comiencen en la línea que dice :CHECKFILE. Muchas cosas aquí son las mismas que con, StartTimer.cmdasí que solo explico líneas nuevas o cambiadas.

Primero verificamos si Timer.start.stateexiste un archivo de estado , si no, terminamos con un mensaje. Si se inició el temporizador y existen archivos, entonces continuamos y hacemos algunos cálculos:
1. Salte a :TIMEOUTdonde producimos los segundos transcurridos. Puede elegir una mejor etiqueta para eso ...
2. SET /P %Timer% ... lee la hora de inicio del archivo y asigna el valor a la %Timer%variable.
3. SET /A Elapsed ... calcula segundos entre la hora de inicio y ahora.
4. ECHO "Seconds ... repite el valor calculado (segundos desde el inicio del temporizador.

Cómo obtener el tiempo restante:

Puedes restar %Elapsed%de %MaxTime%:

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

OK, explicado lo suficiente. Aquí está el guión completo Timer.cmd:

En este punto, olvidé todo lo que ya dije. Este archivo por lotes aquí está funcionando por sí mismo, por lo que no hay por separado StartTimer.cmdo GetTimerValue.cmdsolo esto Timer.cmd. Básicamente sigue siendo el mismo, pero el flujo de código es diferente y el uso también es completamente diferente. Sin embargo, esto no guarda el estado en el archivo, por lo que ya no puede obtener el valor del temporizador después de cerrar sesión / reiniciar, si necesita este ejemplo anterior para guardar / leer el estado en / desde el archivo.

El uso / ayuda para Timer.cmdse imprime cuando se ejecuta sin argumentos. No he probado completamente esto y puede haber algunos errores tipográficos, etc., los argumentos no son infalibles.

@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

Integrar con shutdowno cualquier otro comando:

Archivo poweroff.cmd:

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

Uso: poweroff <wait_seconds>para iniciar el apagado programado y Timer getobtener el tiempo transcurrido / restante.


Te aplaudo por el esfuerzo. Me acabo de dar cuenta de lo mal formulada que estaba la pregunta, pero aun así lograste responderla. Solo por eso obtienes un voto positivo. Desafortunadamente, esto no funciona con comandos de apagado arbitrarios, es decir, StartTimer.cmddebe llamarse explícitamente. Había escrito un pequeño programa para resolver mi problema, que publicaré cuando vuelva a mi computadora.
Bob

Ok, aceptaré esto. Terminé escribiendo un programa C # que fue nombrado shutdown.exe, que llamó shutdown_original.exe. Comprobaría la /tmarca y, si existiera, crearía un archivo con las horas de inicio y finalización guardadas. Al recuperar los tiempos ( /retrievemarca), verificaría el registro de eventos para ver si se realizó un inicio o un aborto desde que comenzó el temporizador. No estoy seguro de cómo habría manejado las hibernaciones. No voy a publicar el código o el programa: es un desastre. Y para que el programa funcionara, tuve que jugar mucho con la configuración de seguridad, que no quiero promover.
Bob

El concepto básico era interceptar la shutdown.exellamada y registrar los tiempos en un archivo, que fue lo que hizo y por qué estoy aceptando esto.
Bob

2
@Bob - ¿Ibas a publicar sobre tu programa cuando regresaste? Enlaces a exe / código fuente?
Alex S
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.