<

Go Premium for a chance to win a PS4. Enter to Win

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
5,064 Points
864 Views
2 Endorsements
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


2
Comment
0 Comments

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

Join & Write a Comment

In this video, viewers will be given step by step instructions on adjusting mouse, pointer and cursor visibility in Microsoft Windows 10. The video seeks to educate those who are struggling with the new Windows 10 Graphical User Interface. Change Cu…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses
Next Article:

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month