Time left before scheduled shutdown?

8

2

Is there any way to view how much time is left before a scheduled shutdown in Windows 7?

By scheduled shutdown I mean a shutdown (or restart) scheduled using the command line shutdown.exe application, e.g.:

shutdown /t 600 /s

That would pop up a message box saying there are 10 minutes until shutdown, and the actual system time of shutdown.

Any time longer than 600 seconds uses a balloon message instead.

I vaguely recall XP providing a GUI progress monitor, with a countdown.

How did they work? The shutdown time left or scheduled time must be stored somewhere, how can I access this?

My preference is some method through the command line (i.e. non-GUI). More importantly, is this accomplishable within Windows, i.e. without any third party programs?

If this is not accomplishable with standard Windows utilities (and I'm bordering on Stack Overflow territory here), is there a Windows API (or .NET, which could even be used in PowerShell!) function? Either would be preferred over some random third party program.

Bob

Posted 2012-04-19T11:11:55.097

Reputation: 51 526

http://superuser.com/a/317062/117590 looked promising, however, it is preferred/required that the shutdown command is not modified as adding a comment (/c <time>) does. – Bob – 2012-04-19T11:16:55.590

I think a batch file wouldn't be hard to write.. Prompt for the time, and every 5 minutes or so it could respond with a time, IE "10 minutes remaining".. and when it gets to 1, count down by seconds or something. – cutrightjm – 2012-04-25T02:00:20.643

I don't need a countdown, I need some method to get the time remaining at <this> moment. The shutdown command is being called by an external program. – Bob – 2012-04-25T02:26:15.867

Answers

5

Question was interesting so I wrote batch that can do job for you.

Basically it is countdown timer, i did not include shutdown command to this but leaved it as homework. Calculations is not accurate, this does not care about leap years, length of month, ... this is mainly for readability as I wanted to keep it easy to learn.

There is currently two files doing job together, one starts timer and other, when called, tells how much time elapsed from timer start. These two files can fairly easily combined into one cmd script, this way you can make some lines reusable (like defined methods) too.

Okay, let's take a look at scripts,

Here is 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 line starting with FOR /F "skip=1 ...:
1. Ask wmic for current time and date.
2. Skip first line of output, which is headings, by skip=1
3. Read values using tokens=1-6 meaning %%a-%%f separated by SpaceorTAB.
4. Store values to variables %DateY%, ... %TimeH%, %TimeM%, ...

After that at line starting SET /A EPOCH=... we use expression that calculates seconds elapsed from 1.1.1970 (this is simple approximate, not real unix time. See Google if you need accurate).

Then at last line ECHO %EPOCH% > ... writes calculated time to file called "Timer.start.state".

And here 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

Here code flow is not linear from top to bottom. First we GOTO CHECKFILE label so execution commands really starts at line that says :CHECKFILE. Many things here is just same as with StartTimer.cmd so I only explain new or changed lines.

First we check if state file Timer.start.state exists, if not then terminate wit message. If timer started and files exists then we continue and do some math:
1. Jump to :TIMEOUT where we output elapsed seconds. You can choose better label for that...
2. SET /P %Timer% ... reads start time from file and assign value to %Timer% variable.
3. SET /A Elapsed ... calculates seconds between start time and now.
4. ECHO "Seconds ... echoes out calculated value (seconds since timer startup.

How to get remaining time:

You can substract %Elapsed% from %MaxTime%:

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

OK, explained enough. Here is full script Timer.cmd:

At this point, forgot everything already said. This batch file here is working on it's own so there is no separate StartTimer.cmd or GetTimerValue.cmd but only this Timer.cmd. Basically it is still same but code flow is different and usage is also completely different. This however does not save state to file so you cant anymore get timer value after logoff/reboot, if you need this use example above to save/read state to/from file.

Usage/help for Timer.cmd is printed when run without arguments. I have not fully tested this and there may be some typos etc., args are not foolproof checked.

@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

Integrate with shutdown or any other command:

File poweroff.cmd:

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

Usage: poweroff <wait_seconds> to start timed shutdown and Timer get to get elapsed/remaining time.

Sampo Sarrala - codidact.org

Posted 2012-04-19T11:11:55.097

Reputation: 2 268

2@Bob - You were going to post about your program when you got back? Links to exe/ source code? – Alex S – 2016-04-16T22:08:21.220

I applaud you for the effort. I just realised how badly phrased the question was, but you still managed to answer it. Just for that you get an upvote. Unfortunately, this does not work with arbitrary shutdown commands, i.e. StartTimer.cmd must be explicitly called. I had written a small program to solve my problem, which I'll post when I get back to my computer. – Bob – 2012-05-14T22:24:56.030

Ok, I'll accept this. I ended up writing a C# program that was named shutdown.exe, which called shutdown_original.exe. It would check for the /t flag and if it existed, create a file with start and end times saved. On retrieving times (/retrieve flag), it would check the event log to see if a startup or abort was performed since the timer started. I'm not sure how it would have handled hibernations. I'm not going to post the code or program: it's a buggy mess. And to get the program to work, I had to mess around a lot with security settings, which I don't want to promote. – Bob – 2012-05-16T04:53:17.180

The basic concept was intercepting the shutdown.exe call and logging the times to a file, which was what you did and why I'm accepting this. – Bob – 2012-05-16T04:54:43.670