Environment.TickCount is not enough

codebased picture codebased · Jan 10, 2011 · Viewed 12.3k times · Source

I want to know on when was the last time the system was started.

Environment.TickCount will work but it is breaking after 48-49 days because of the limitation of int.

This is the code I've been using:

Environment.TickCount & Int32.MaxValue

Does anyone knows about long type return somehow?

I am using this to know the idle time of the system:

public static int GetIdleTime()
{
    return (Environment.TickCount & Int32.MaxValue)- (int)GetLastInputTime();
}

/// <summary>
/// Get the last input time from the input devices.
/// Exception: 
/// If it cannot get the last input information then it throws an exception with 
/// the appropriate message.
/// </summary>
/// <returns>Last input time in milliseconds.</returns>
public static uint GetLastInputTime()
{
    LastInputInfo lastInPut = new LastInputInfo();
    lastInPut.BlockSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(lastInPut);
    if (!GetLastInputInfo(ref lastInPut))
    {
        throw new Exception(GetLastError().ToString());
    }

    return lastInPut.Time;
}

Answer

Philm picture Philm · May 3, 2017

The following code retrieves the milliseconds since system start (call to unmanged API). I measured the performance costs for that interop operation, and it is quite identical to StopWatch() (but that doesn't retrieve the time since system start directly of course).

using System.Runtime.InteropServices;

...

[DllImport("kernel32.dll") ]
public static extern UInt64 GetTickCount64();

...

var tickCount64 = GetTickCount64();

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