System Up Time

Windows specific forum
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by boop64.

Here is a short piece of code I wrote to get the current system up time I hope it helps someone out there.

;-------------------------------------
;A simple procedure that will return the current system uptime
Procedure.s uptime()
uptime.f = GetTickCount_() ;gets the system uptime in miliseconds
;determine hours
upth.f = uptime/3600000
;determine minutes
rmnd.f = upth - Round(upth,0)
uptm.f = rmnd*60
;determine seconds
rmnd = uptm - Round(uptm,0)
upts.f = rmnd*60
;determine miliseconds
rmnd = upts - Round(upts,0)
uptms.f = rmnd*1000
;Format the string to H:M:S.MS
sysuptime.s = Str(upth) + ":" + Str(uptm) + ":" + Str(upts) + "." + Str(uptms)
ProcedureReturn sysuptime
EndProcedure

MessageRequester("System Up Time", uptime(),0)
;------------------------------------

It's simple, it's short and best of all.... it works! :wink: If you like this sample or want to complain about it leave a post.

Boop64
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by PB.

> uptime.f = GetTickCount_() ;gets the system uptime in miliseconds

Don't forget that GetTickCount resets after 49 days, so if your PC's
uptime normally goes longer than that, then problems will arise.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by boop64.
Originally posted by PB
Don't forget that GetTickCount resets after 49 days, so if your PC's
uptime normally goes longer than that, then problems will arise.
Thanks, I did not know that. I just came accross it while I was teaching my self to use the windows api with purebasic. Just for reference, how would get the system uptime after that 49 days? Is there another function to do it or would you have to make your program keep track of it by logging the uptime?

Boop64
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by ebs.

Boop64,

It resets after approximately 49 days because the number of milliseconds is held in a 32-bit number:

2**32 = 4,294,967,296

and 49 days of milliseconds is:

49 * 24 * 60 * 60 * 1,000 = 4,233,600,000

It sounds like a good idea to have your program record each 49 days of uptime.

Regards,
Eric
Originally posted by boop64
Originally posted by PB
Don't forget that GetTickCount resets after 49 days, so if your PC's
uptime normally goes longer than that, then problems will arise.
Thanks, I did not know that. I just came accross it while I was teaching my self to use the windows api with purebasic. Just for reference, how would get the system uptime after that 49 days? Is there another function to do it or would you have to make your program keep track of it by logging the uptime?

Boop64
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by freak.

There's another thing you need to be aware of:

PureBasics Variables are SIGNED! This means, after 24.5 Days, GetTickCount_() returns negative Values.

Timo
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by boop64.
Originally posted by freak

There's another thing you need to be aware of:

PureBasics Variables are SIGNED! This means, after 24.5 Days, GetTickCount_() returns negative Values.

Timo
How would you fix this problems?.... Couldn't you just take the absolute value of the tick count, something similar to this?
uptime.f = GetTickCount()
uptime = abs(uptime)
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by pusztry.

Is there a good way to get it past the ~49 day limit? Could you use a log file some how? I am struggleing with this. I could realy use some help.


- Ryan


WinXP, PIII 800 MHz, 512MB RAM, SB Live 5.1, NVidia TNT 2 Ultra
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by PB.

> Is there a good way to get it past the ~49 day limit?

If you just want to record the uptime with a per-second accuracy (not
a per-millisecond accuracy), then just use the tip I gave here:

viewtopic.php?t=2777
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by boop64.
Originally posted by pusztry

Is there a good way to get it past the ~49 day limit?
One way you could log the uptime is to write the uptime to an ini file or you could use the registry like I am doing. And once you have written the value of the current uptime make a fuction that compares the current uptime value to the stored uptime value... something similar to this:
;Use an if statement similar to this once you have loaded
;the StoredUpTime from the file or registry
If CurrentUpTime < StoredUpTime
StoredUpTime = StoredUpTime + CurrentUpTime
Else
StoredUpTime = CurrentUpTime
EndIf
;Then write the value of the StoredUptime

PS. you want to write your stored up time in seconds not miliseconds or you will run into the same problem with the 49 day thing.
This is just a simple fix, but the way I'm storing the uptime is a little differn't. I store the houre, minutes, seconds, and miliseconds seperately. You would use code similar to above to compare each one. This method is the best i have found so far.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

Does anyone know how to reliably get the PC's uptime without using
GetTickCount or ElapsedMilliseconds? Preferably with a short snippet.

I found this, is it easily convertable to PureBasic?

Code: Select all

Set objWMIService=GetObject("winmgmts:\\.\root\cimv2")
Set colOperatingSystems=objWMIService.ExecQuery _
  ("Select * From Win32_PerfFormattedData_PerfOS_System")
For Each objOS in colOperatingSystems
  intSystemUptime=Int(objOS.SystemUpTime)
  TimedAt=FormatDateTime(Date(),2) &", " &FormatDateTime(Time(),4)
  Msgbox UpTime(intSystemUptime)
Next
Function UpTime(S)
  M=S\60 : S=S mod 60 : H=M\60 : M=M mod 60 : D=H\24
  UpTime=D &" Days, " & H MOD 24 &" Hours, " &M &" Minutes"
End Function
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

This should be reliable on XP though slow:

Code: Select all

program = RunProgram("systeminfo.exe","","",#PB_Program_Open|#PB_Program_Read|#PB_Program_Hide)
While ProgramRunning(program)
  If AvailableProgramOutput(program)
    a$=ReadProgramString(program)
    If FindString(a$, "System Up Time", 1)
      uptime$ = a$
      KillProgram(program)
    EndIf
  EndIf
  Delay(1)
Wend
MessageRequester("",uptime$,$c0)
I'm sure it's located in the registry and you can just read it directly, so a little research might yield a faster proc. Not sure if it works on Vista or 7.
BERESHEIT
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

There is also the GetSystemTimes_( ) API, which returns three times: idle time, kernel mode time and user time. iirc these are totals, so if you add them up they should equal uptime. But I haven't done it so I can't say for sure. If it works though, it's probably the best approach, better than reading the registry or running OS programs in the background.
BERESHEIT
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Using srod's COMate...

Code: Select all

XIncludeFile "COMate.pbi"

Procedure.s UpTime_Info() 
  Define.COMateObject objWMIService, UpTime 
  colUpTime.COMateEnumObject 
  strComputer.s = "." 
  objWMIService = COMate_GetObject("winmgmts:\\" + strComputer + "\root\cimv2", "") 
  If objWMIService 
    colUpTime = objWMIService\CreateEnumeration("ExecQuery('Select * from Win32_PerfFormattedData_PerfOS_System')") 
    If colUpTime 
      UpTime = colUpTime\GetNextObject() 
      myUpTime = UpTime\GetIntegerProperty("SystemUpTime")
      uMinutes = myUpTime/60
      uSeconds = myUpTime%60
      uHours = uMinutes/60
      uMinutes = uMinutes%60
      uDays = uHours/24
      upTimeDuration$ = Str(uDays) + " Days" + #crlf$
      upTimeDuration$ + Str(uHours) + " Hours" + #crlf$
      upTimeDuration$ + Str(uMinutes) + " Minutes" + #crlf$
      upTimeDuration$ + Str(uSeconds) + " Seconds" + #crlf$
      startUpTime = Date() - myUpTime
      startUpTime$ = FormatDate("%mm/%dd/%yyyy  %hh:%ii:%ss", startUpTime)
      MessageRequester("System Up Since", startUpTime$ + #crlf$ + #crlf$ + upTimeDuration$)
      UpTime\Release() 
      colUpTime\Release() 
    EndIf 
    objWMIService\Release()  
  EndIf 
EndProcedure 

UpTime_Info()
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5502
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

netmaestro wrote:This should be reliable on XP though slow:

Code: Select all

program = RunProgram("systeminfo.exe","","",#PB_Program_Open|#PB_Program_Read|#PB_Program_Hide)
While ProgramRunning(program)
  If AvailableProgramOutput(program)
    a$=ReadProgramString(program)
    If FindString(a$, "System Up Time", 1)
      uptime$ = a$
      KillProgram(program)
    EndIf
  EndIf
  Delay(1)
Wend
MessageRequester("",uptime$,$c0)
I'm sure it's located in the registry and you can just read it directly, so a little research might yield a faster proc. Not sure if it works on Vista or 7.
For info this code Return nothing at my home XP PRO SP2 :cry:

@Sparkie
Your code works fine

Thanks at you two 8)
ImageThe happiness is a road...
Not a destination
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

Thanks to Freak I was able to come up with this, which works perfectly:

Code: Select all

QueryPerformanceFrequency_(@perSec.q)

For a=1 To 10
  QueryPerformanceCounter_(@currTime.q)
  Debug FormatDate("%hh:%ii:%ss",currTime/perSec)
  Sleep_(1000)
Next
No need for program outputs, Registry, COMate, etc. ;) Many thanks must
go to netmaestro and Sparkie for taking the time to post their solutions.

(BTW: I know this only works for 24 hours, but should be easy to enhance).
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Post Reply