Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Uptime with Win32::GetTickCount()

by BioHazard (Pilgrim)
on Dec 02, 2002 at 12:09 UTC ( [id://216892]=perlquestion: print w/replies, xml ) Need Help??

BioHazard has asked for the wisdom of the Perl Monks concerning the following question:

Fellow Monks,

I am recording the system uptime of my machine with a script shown below. By the time it is up for 49 days and 22 hours. Windows (XP) tells me so and a few other programs, too. Since this morning my Perl Script tells me:
Uptime: 0 days, 5 hours
The machine definitely did not reboot. So what is wrong with Win32::GetTickCount()?

Of course, there is another script which parses the milliseconds in days, hours, etc. But the main point is that the value of Win32::GetTickCount() seems to overswap or seems to do something else in a way.

Has anyone an idea? Thanks :)
Here's the script:

#!C:/Perl/bin/perl use strict; use Win32; use XML::Simple; my ($uptime, $xml, $lastupdate); while (1) { $uptime = Win32::GetTickCount(); $xml = XMLin("reg.xml", 'searchpath' => ['C:/Programme/Apache Grou +p/Apache/cgi-bin/uptime'], 'noattr' => 1); $xml->{'uptime'} = $uptime; if ($uptime > $xml->{'record'}) { $xml->{'record'} = $uptime; } $lastupdate = time(); $xml->{'lastupdate'} = $lastupdate; XMLout($xml, 'outputfile' => 'C:/Programme/Apache Group/Apache/cgi +-bin/uptime/reg.xml', 'noattr' => 1); sleep(600); } exit;

BioHazard
reading between the lines is my real pleasure

Replies are listed 'Best First'.
Re: Uptime with Win32::GetTickCount()
by BrowserUk (Patriarch) on Dec 02, 2002 at 12:29 UTC

    The problem is that the value is either being stored by Windows (or possible returned by Win32::GetTickCount() I haven't been able to find the info on this yet) as an 32-bit value. This gives a maximimum milliseconds counts of 4294967295 which translates to 49 days 15 hours 37 minutes 33.354 seconds.

    If I manage to locate the information as to whether this is an OS limitation or if its the module wrapper that is throwing information away, I'll update this post.

    Update: I found an appropriate page on msdn

    The elapsed time is stored as a DWORD value. Therefore, the time will wrap around to zero if the system is run continuously for 49.7 days.

    Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
    Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
    Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
    Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.

      Thanks a lot :)
      Too bad for people with the "Uptime-Hobby"

      I am quite lazy right now and just added the line
      $uptime += 4294967295;
      to my script. I know that I have to do this again in 49.7 days ;-)
      But is there perhaps another method or another module which gets another system (uptime) variable? There must be a environment variable showing the correct uptime, because Windows tells me the correct value and a program called "tuxtime uptime client" ( tuxtime community ) as well.

      BioHazard
      reading between the lines is my real pleasure

        A quick google turned up this perl script which uses various means to work around the 49 day roll-over under windows of various flavours.

        The relevant bit for win2k is the bit that locates the 6005 event in the event log.


        Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
        Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
        Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
        Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.

      This gives a maximimum milliseconds counts of 4294967295 which translates to 49 days 15 hours 37 minutes 33.354 seconds.

      Which, incidentially, made earlier versions of Windows crash after this amount of uptime. Not that I ever heard of anyone having an uptime of 49 days with Win 95, though. :)

Re: Uptime with Win32::GetTickCount()
by guha (Priest) on Dec 07, 2002 at 15:48 UTC

    In my previous post in this thread I assumed from your code snippet that you wanted the script to run more or less like a daemon and that you you would start the script in the boot process. Then brother BrowserUk objected that this was not necessarily the case.

    For that case all use of Win32::GetTickCount won't work either, since you don't know how many 49 day wraps that has occurred already when you start the script.

    On XP however I suggest the following solution, which is based on the fact that the file C:\windows\bootstat.dat is touched at bootup.

    #!perl -w use strict; my $file = 'c:/windows/bootstat.dat'; -e $file or die "no $file"; my $boot_days_ago = -M $file; my $boot_secs_ago = 86400 * $boot_days_ago; my $boot_time = int ( time - $boot_secs_ago) ; while(1) { my $t = time-$boot_time; printf "%4d h %2d m\r", int($t/3600), int(($t%3600)/60); sleep 1; }

    On NT or Win2k systems however the said file does not exist but then the program Uptime from Microsoft can be useful.
    The article describes some if's and but's on the issue.

Re: Uptime with Win32::GetTickCount()
by guha (Priest) on Dec 04, 2002 at 22:27 UTC
    Since you don't seem interested in fine resolution timing I figure you could get away with:
    my $uptime = time()-$^T;

    or check out the docs for the times function.

    This way I expect your hardware to wrap over before your script ;-)

      That's not going to help unless the script performing your calculation is run at boot-time and left running always. $BASETIME ($^T) is the time when the script was started not when the system was started.


      Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
      Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
      Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
      Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.

Re: Uptime with Win32::GetTickCount()
by Anonymous Monk on Oct 09, 2014 at 16:03 UTC

    I just posted to http://www.perlmonks.org/?node_id=433565 (Converting POSIX format date/times to epoch seconds) a change to convert the WMIC boot time output. not sure if it would work for older systems but it works on Windows 7. requires use of the (not so great named) HTTP::Date package and a simple modification. code allows use of WMIC command to get the seconds at time of boot and time() can be used at that point to get the up time. GetTickCount was giving me a time (in ms) of 13 days up time on my system which has been up for 150+ days - the change to HTTP::Date is small and allowed me to report the correct up time.

      if you have wmic then here is a program to convert the wmic format boot time to seconds then redisplay it. I cloned the HTTP::Date code then chopped it down to this. also being posted on http://www.perlmonks.org/?node_id=433565

      use strict; use Time::Local; sub wmic2time (;$) { my $wmic_time_in=$_[0]; if(!defined $wmic_time_in) { $wmic_time_in=join " ",`wmic os get lastbootuptime 2>&1`; $wmic_time_in=~s/\r\n/ /g; $wmic_time_in=~s/ * / /g; } $wmic_time_in=~s/LastBootUpTime //i; # caller may have remove +d this already but just in case.... my @d = $wmic_time_in =~ /^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/x +; # year numerical month day Hour Min Sec return undef unless @d; $d[1]--; # month return eval { my $t = Time::Local::timelocal(reverse @d); $t < 0 ? undef : $t; }; } my $newtime=wmic2time; print "$newtime\n"; print scalar localtime $newtime . "\n";
Re: Uptime with Win32::GetTickCount()
by ibanix (Hermit) on Dec 02, 2002 at 14:48 UTC
    use anal-retentive;

    Just wanted to point out that #!C:\perl\bin\perl doesn't do anything. Win32 ignores it.

    <-> In general, we find that those who disparage a given operating system, language, or philosophy have never had to use it in practice. <->
      Yes, you're right, but I usually write CGI Scripts for my webserver and those do need the (Windows-)shebang line. As I said a few posts above, I'm quite lazy at the moment and did not delete this line ;-)

      BioHazard
      reading between the lines is my real pleasure

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://216892]
Approved by Tanalis
Front-paged by tye
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2024-04-20 02:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found