<

Expiring Today—Celebrate National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x

How to solve the problem of incorrect System Uptime being reported when a system has been up for a long time (approximately 50 days or more)

Published on
4,742 Points
642 Views
1 Endorsement
Last Modified:
Joe Winograd, EE MVE 2015&2016
50+ yrs in computer industry. Everything from programming to sales. OS kernel dev on mainframes. CIO. Document imaging. EE MVE 2015 & 2016.
The Windows functions GetTickCount and timeGetTime retrieve the number of milliseconds since the system was started. However, the value is stored in a DWORD, which means that it wraps around to zero every 49.7 days. This article shows how to solve that problem by using the GetTickCount64 function.

In an interesting question posted here at Experts Exchange, a member asked for a program/script that would perform a reboot if a Windows system has been up for more than a specified amount of time (in his company's case, the IT standard for this is more than 14 days). He also wants an option so that the user can delay the reboot for a specified amount of time (in his company's case, 15 minutes), but a "nag" dialog would continue to be re-displayed until the user finally agrees to a reboot.


Key to a solution for this is the ability to determine how long it has been since a system was started. Fortunately, Windows knows this and makes it available via function calls. One of the function calls is GetTickCount and is documented here:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms724408(v=vs.85).aspx


Another function is timeGetTime, documented here:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd757629(v=vs.85).aspx


Both of them perform similarly, i.e., returning the elapsed milliseconds since the system was started. Some scripting/programming languages use this capability to make the system uptime available in a built-in variable. For example, the AutoHotkey language has a built-in variable called A_TickCount, which it defines as:

The number of milliseconds since the computer was rebooted.


Using this built-in variable, here's one line of AutoHotkey code that calculates the system uptime in days:


UptimeDays:=(A_TickCount/1000)/(60*60*24)


Well, close, but no cigar! Why? If you read the Microsoft documentation referenced above, you'll see that GetTickCount and timeGetTime both store the value in a DWORD. Because of this, they work for up to 49.7 days only!


To overcome this limitation, Windows provides the GetTickCount64 function, documented here:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms724411(v=vs.85).aspx


This returns the elapsed milliseconds since the system was started, but without the 49.7 day limitation.


If your programming/scripting language doesn't provide that as a built-in variable, you should be able to make a DLL call to get it. For example, in AutoHotkey, this will retrieve it:


TickCount64:=DllCall("Kernel32.dll\GetTickCount64","UInt64")


Here's a working AutoHotkey script that shows everything mentioned above:


BuiltInTC:=A_TickCount
GetTC:=DllCall("Kernel32.dll\GetTickCount","UInt")
timeGT:=DllCall("Winmm.dll\timeGetTime","UInt")
GetTC64:=DllCall("Kernel32.dll\GetTickCount64","UInt64")
MsgBox,,Uptime Tests,BuiltInTC=%BuiltInTC%`nGetTC=%GetTC%`ntimeGT=%timeGT%`nGetTC64=%GetTC64%


I ran that script on a WS2012R2 system that had been up for more than 49.7 days. Here's the result:



On the same WS2012R2 system, I then ran another AutoHotkey script that calculates the uptime in days based on both the A_TickCount built-in variable and a call to the GetTickCount64 function. Here's the result:



Problem solved!  Note that 87.3-37.6=49.7, which shows that, because of the DWORD limitation, the count essentially starts over at zero every 49.7 days — hence, the need to call GetTickCount64.


Here's a complete, tested AutoHotkey script, based on calling GetTickCount64, that satisfies the requirements specified in the first paragraph of this article:


#Warn,UseUnsetLocal ; warning on uninitialized variables
#NoTrayIcon ; do not show an icon in the system tray
#NoEnv ; avoid checking empty variables to see if they are environment variables
#SingleInstance ignore ; leave old instance running
SetBatchLines,-1 ; run at maximum speed
SetFormat,float,0.1 ; uptime in days to one decimal place

; begin params you may want to change
UptimeDaysLimit:=14
NagTimeMinutes:=30
; end params you may want to change

NagTime:=1000*60*NagTimeMinutes ; param to Sleep is in milliseconds
NagAgain:
UptimeMilliseconds:=DllCall("Kernel32.dll\GetTickCount64","UInt64")
UptimeDays:=(UptimeMilliseconds/1000)/(60*60*24)
If (UptimeDays>UptimeDaysLimit)
{
  ; MsgBox options (https://autohotkey.com/docs/commands/MsgBox.htm):
  ; 1 - Buttons are OK and Cancel
  ; 48 - Icon is exclamation
  ; 256 - Second button is default (to avoid accidental Enter key causing a reboot)
  ; 4096 - Dialog is always on top
  MsgBox,4401,System Uptime Warning,Your system has been up for %UptimeDays% days`n`nClick OK to reboot now or Cancel to be reminded again in %NagTimeMinutes% minutes
  IfMsgBox,OK
  {
    ; Shutdown options (https://autohotkey.com/docs/commands/Shutdown.htm):
    ; 0 - Logoff
    ; 1 - Shutdown
    ; 2 - Reboot
    ; 4 - Force
    ; 8 - Power down
    Shutdown,2
  }
  Else
  {
    Sleep,%NagTime%
    Goto,NagAgain
  }
}
ExitApp


I commented the code heavily to serve as documentation for it, but if you have questions about how it works, please post here and I'll be happy to try to answer.


Sidebar:

If you're not familiar with AutoHotkey and this article has piqued your interest in it, this other EE article will help you to get started with it:

AutoHotkey - Getting Started

End Sidebar


As a final comment on the issue of determining system uptime, it has been documented that TickCount functions can be inaccurate in Windows 10 because of the Fast Startup feature, which is enabled by default in W10. You may disable it (when logged in as an admin) as follows:


Control Panel

Power Options

Choose what the power buttons do

Change settings that are currently unavailable


You'll see this:



Un-check the Turn on fast startup (recommended) box, which will be checked by default (if you don't have that box, it means that Hibernation is not enabled).


If you find this article to be helpful, please click the thumbs-up icon below. This lets me know what is valuable for EE members and provides direction for future articles. Thanks very much! Regards, Joe


1
Comment
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
0 Comments

Featured Post

NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

Join & Write a Comment

Windows 8 came with a dramatically different user interface known as Metro. Notably missing from that interface was a Start button and Start Menu. Microsoft responded to negative user feedback of the Metro interface, bringing back the Start button a…
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…
Next Article:

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month