4

Im trying to use the GetTickCount() in Windows API to get the system uptime. I want to know how long the system has been running.

However the return from GetTickCount is insanely high. This code gives me uptime of over 500 hours.

This goes for GetTickCount64() as well.

Why is this value so high?

DWORD time_ms = GetTickCount();
DWORD seconds = (time_ms / 1000) % 60;
DWORD minutes = time_ms /(1000*60) % 60;
DWORD hours = time_ms / (1000*60*60);
stringstream ss;
ss << "Hours: ";
ss << hours;
ss << " Minutes: ";
ss << minutes;
ss << " seconds: ";
ss << seconds;
MessageBoxA(0, ss.str().c_str(), "Uptime", 0);

As i run the program I can see that it is progressing correctly, but cannot comprehend how I will get the total uptime for my desktop.

Thanks

Edit: I checked the uptime with "systeminfo" in CMD and found that the "System boot time" was actually aprox ~500hours ago. So I shut down the computer and unplugged the electricity, booted but still,the System boot time had this high value. However, restarting the computer made it reset, and now my code works.

EDIT 2: This blog https://blogs.msdn.microsoft.com/oldnewthing/20141113-00/?p=43623 states that GetTickCount should rather be used for measuring time intervals than what I'm trying to achieve. Seems like I have to look at the registry.

EDIT 3:

After finding the right counter in the registry, it has the same value has GetTickCount and similar functions. It seems that shut down in Windows brings it to some sort of hibernation. I have not found any solution to this.

Gurra
  • 135
  • 1
  • 10
  • 1
    Your code has always worked, subject to the 32 but, 49 day wrap around that can be fixed with `GetTickCount64`. Your edits suggest that you don't have a very clear idea of what you are doing at all. The registry is not the place to look for uptime. I wonder if you are really opening your mind properly to this problem. – David Heffernan Feb 10 '16 at 15:22
  • 1
    It seems you don't really understand that I did shutdown the computer, unplugged the cable and waited for a minute. Still the system uptime was that of 500 hours. Do you think I'm trying to fool anyone? Whats the problem? – Gurra Feb 10 '16 at 15:27
  • It was not until I rebooted that it actually rested. – Gurra Feb 10 '16 at 15:28
  • 1
    Never mind. This is not productive. – David Heffernan Feb 10 '16 at 15:30

4 Answers4

5

The documentation for GetTickCount describes the correct way to get the system up-time:

To obtain the time elapsed since the computer was started, retrieve the System Up Time counter in the performance data in the registry key HKEY_PERFORMANCE_DATA. The value returned is an 8-byte value. For more information, see Performance Counters

Jonathan Potter
  • 36,172
  • 4
  • 64
  • 79
  • Well this answers how to get the Uptime, thx. I will do an edit to display some other findings I did. – Gurra Feb 10 '16 at 15:14
3

I just had the same problem. I solved it by :

  • using the restart command rather that shutting down the computer : this performs a true restart of the computer and not a "half-hibernation" like the shutdown command when the "fast startup" is enabled
  • disabling the "fast startup" option. This fast startup option leads to a non reseted GetTickCount at startup !!

I guess that a lot of old programs will bug again with W10 and the fast startup option...

Phuphus
  • 31
  • 1
1

500 hours uptime is not especially surprising. That's around 20 days. Modern systems are seldom shutdown. Typically they are suspended rather than shutdown. I think your system really has been up for 500 hours.

Of course, you should be using GetTickCount64 to work with a 64 bit tick count. That will avoid the 49 day wrap around that is a consequence of the 32 bit values returned by GetTickCount.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
1

Im trying to use the GetTickCount() in Windows API to get the system uptime. I want to know how long the system has been running.

In addition to what others have said, there is another alternative solution.

You can call NtQuerySystemInformation() from ntdll.dll, setting its SystemInformationClass parameter to SystemTimeOfDayInformation to retrieve a SYSTEM_TIMEOFDAY_INFORMATION structure containing BootTime and CurrentTime fields as LARGE_INTEGER values:

typedef struct _SYSTEM_TIMEOFDAY_INFORMATION {
    LARGE_INTEGER BootTime;
    LARGE_INTEGER CurrentTime;
    LARGE_INTEGER TimeZoneBias;
    ULONG TimeZoneId;
    ULONG Reserved;
    ULONGLONG BootTimeBias;
    ULONGLONG SleepTimeBias;
} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION;

You can simply subtract BootTime from CurrentTime to get the elapsed time that Windows has been running (this is exactly how Task Manager calculates the "System Up Time").

How to get Windows boot time?

How does Task Manager compute Up Time, and why doesn’t it agree with GetTickCount?

Community
  • 1
  • 1
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks! I will look into this today. – Gurra Feb 11 '16 at 07:15
  • I am unfortunately not successful with this, according to your link to MSDN the `SystemTimeOfDayInformation` does retrieve a `SYSTEM_TIMEOFDAY_INFORMATION` but this does not have the `BootTime` field. It seems to be used for randomizing instead. I may be wrong but I didnt get it to work. – Gurra Feb 11 '16 at 08:51
  • 1
    @Gurra: I assure you, the real data actually has `BootTime` and `CurrentTime` fields (I use them in my code, so I know they work). MSDN is simply hiding the fields from documentation. I have included the "real" declaration in my answer now. – Remy Lebeau Feb 11 '16 at 23:07
  • OK, I will try again next week. I did try and use this but will include some of my code next time i try. Thanks! – Gurra Feb 13 '16 at 11:34