WinBatch® Technical Support Forum

All Things WinBatch => WinBatch => Topic started by: snowsnowsnow on June 29, 2013, 08:06:30 AM

Title: UPTIME - revisited (again)
Post by: snowsnowsnow on June 29, 2013, 08:06:30 AM
I know this was discussed recently, but I was not satisfied with the answer(s) given there.  I did raise some issues there that were not very well answered (IMHO, of course).  I am hoping for a better outcome here.

The question is: What's the best way to get the system uptime in WB?

Now, note that when people (and, in this case, "people" is me) ask about uptime, they are really asking 3 distinct, though related, questions:

1) When was the system (most recently) booted?  (date/time)
2) How long ago was the system (most recently) booted?  (duration)
3) How long has the system actually been up (i.e., functional) (since the most recent boot)?

Note that 1 & 2 are equivalent - meaning that, provided you know the current date/time, either can be calculated from the other.  And, of course, 2 & 3 would be identical provided the system has never been suspended (hibernated, whatever).

So, given that they are all different concepts, what is the best way to get each/all of these values, in WB (using, presumably, DllCalls and/or WMI) ?
Title: Re: UPTIME - revisited (again)
Post by: DAG_P6 on June 29, 2013, 10:52:57 PM
I would look to the System Event Log for the answers. Although I don't recall off the top of my head the ID number, I know that system restart registers a specific event ID. Its time stamp answers questions 1 and 2. The third question is probably best answered by the last message that a service has entered the running state, recorded by the Service Control Manager following the restart. Service Control Manager assigns a specific ID to those messages, too.

With a tad of help from the COM interface to LogParser, it should be straightforward. In that regard, be sure to check out the Checkpoint file, which enables you to reliably extract events since the last extract of that kind ran. You can associate separate checkpoint files with each query.
Title: Re: UPTIME - revisited (again)
Post by: stanl on June 30, 2013, 11:40:31 AM
In PS it is a simple 2-liner (see jpeg). This can be run from a batch file with WBxxxx or WB2013 through the CLR interface. Or use WMI (more code, but works with earlier versions). Then there is always the code Tony posted using the Performance counter which requires WB013.
Title: Re: UPTIME - revisited (again)
Post by: Deana on July 01, 2013, 08:51:23 AM
Let me start by saying that WinBatch doesn't have any built in functions to handle this. So this becomes a broader programming question rather than a specific WinBatch question. I suspect that is why you felt that it was "not very well answered".  I personally do not know the answer. If your lucky maybe someone else here does and will take the time to post a response.
Title: Re: UPTIME - revisited (again)
Post by: Deana on July 01, 2013, 09:09:10 AM
Here is my attempt at answering questions one and two....

Code (winbatch) Select
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Last Boot Time
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
oItems = oWMI.ExecQuery("Select * from Win32_OperatingSystem")
ForEach oItem In oItems
   Date = StrSub(oItem.LastBootUpTime,1,14)
Next
Y = StrSub(Date,1,4)
M = StrSub(Date,5,2)
D = StrSub(Date,7,2)
H = StrSub(Date,9,2)
MM = StrSub(Date,11,2)
S = StrSub(Date,13,2)
LastBootTime = Y:":":M:":":D:":":H:":":MM:":":S
Message("LastBootTime",LastBootTime)
oItems = 0
oWMI = 0

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Duration
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

duration = TimeDiff(TimeYMDHMS(),LastBootTime)
Message("Duration",duration)
Title: Re: UPTIME - revisited (again)
Post by: Deana on July 01, 2013, 09:19:57 AM
Here is a possible answer for question 3 ( posted previously by Tonyd) :
Code (winbatch) Select

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;This gives you the System Up Time without including the time the OS may have been suspended or in hibernation.
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   
; Get an instance of the System Up Time performance counter.
ObjectClrOption("use", "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
UpTime = ObjectClrNew("System.Diagnostics.PerformanceCounter", "System", "System Up Time", "")

; Two read counter.
UpTime.NextValue();
nSecs = UpTime.NextValue()
UpTime.Close()

Message("System Up Time", nSecs: " Seconds")


NOTE: To read performance counters in Windows Vista, Windows XP Professional x64 Edition, or Windows Server 2003, you must either be a member of the Performance Monitor Users group or have administrative privileges.

Reference: http://msdn.microsoft.com/en-us/library/z0wssx8x.aspx
Title: Re: UPTIME - revisited (again)
Post by: Deana on July 01, 2013, 09:27:12 AM
Question 3: The following API looks interesting: http://msdn.microsoft.com/en-us/library/windows/desktop/dd405535(v=vs.85).aspx. The QueryUnbiasedInterruptTime Function gets the current unbiased interrupt time from the biased interrupt time and the current sleep bias amount. This time is not affected by power management sleep transitions. If running on Windows 7 or newer you might be able to use DllCall for this API.

See also: http://msdn.microsoft.com/en-us/library/windows/desktop/ee662306(v=vs.85).aspx
Title: Re: UPTIME - revisited (again)
Post by: snowsnowsnow on July 01, 2013, 11:42:13 AM
Thanks Deana.  This gives me something to work with.