Environment.TickCount is not enough

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

Environment.TickCount will work, but it is interrupted after 48-49 days due to int restriction.

This is the code I used:

Environment.TickCount & Int32.MaxValue

Does anyone know about returning a long type?

I use this to find out the system downtime:

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;
}
+3
source share
6 answers
public void BootTime(){    
    SelectQuery query = new SelectQuery("SELECT LastBootUpTime FROM Win32_OperatingSystem WHERE Primary='true'");
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);

    foreach (ManagementObject mo in searcher.Get())
    {
        DateTime dtBootTime = ManagementDateTimeConverter.ToDateTime(mo.Properties["LastBootUpTime"].Value.ToString());
        Console.WriteLine(dtBootTime.ToString());
    }
}
+8
source

You are correct that it Environment.TickCountwill overflow after about 25 days, because the return value is a 32-bit integer.

, TickCount, , . , , . , .

- PerformanceCounter class ( System.Diagnostics), . :

TimeSpan upTime;
using (var pc = new PerformanceCounter("System", "System Up Time"))
{
    pc.NextValue();    //The first call returns 0, so call this twice
    upTime = TimeSpan.FromSeconds(pc.NextValue());
}
Console.WriteLine(upTime.ToString());

WMI. stian.net, .

, , , Windows, "System" "System Up Time", PdhLookupPerfNameByIndex, , PdhAddEnglishCounter , Vista . .

+6

( API). , StopWatch() ( ).

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

+2

, 64- TickCount, 2 ^ 63 (292 ) 2 ^ 64 (585 ). 1 ( 10-16 ) , 1000 49 710 (136 ) UInt32.

GetTickCount64() , Vista .

, TickCount.

// C# (untested)
...
// Initialize and start timer:
uint uiT0 = unchecked((uint)Environment.TickCount);  // T0 is NOW.  // ms since boot, 10-16ms res.
uint uiElapsedPrev = 0;
uint uiWrapCount = 0;
...
long x = GetElapsedTime();

public static long GetElapsedTime()
{
    uint uiElapsed = unchecked((uint)Environment.TickCount - uiT0)  // 0 to +49.71 days

    if (uiElapsed < uiElapsedPrev)  // IF uiElapsed decreased,
        uiWrapCount++;  // increment the wrap counter.
    uiElapsedPrev = uiElapsed;  // Save the previous value.

    return ( ((long)uiWrapCount << 32) + (long)uiElapsedPrev );
}

Int32.MaxValue .NET. 32- . Environment.TickCount . , . : : uiT0 = Int32.MaxValue; iTickNow = uiT0 + 1 Int32.MinValue; , (iTickNow - uiT0) 1.

uiElapsed 49,7 , . , , iWrapCount . GetElapsedTime() 49.7 , .

0

, , .

0 , min 0.

https://msdn.microsoft.com/en-us/library/system.environment.tickcount(v=vs.110).aspx

, http://www.codeproject.com/Articles/13384/Getting-the-user-idle-time-with-C

?

    Public Shared Function GetIdle() As UInteger
        Dim lii As New LASTINPUTINFO()
        lii.cbSize = Convert.ToUInt32((Marshal.SizeOf(lii)))
        GetLastInputInfo(lii)

        Dim totalTicks As Long = 0

        If Environment.TickCount > 0 Then
            totalTicks = Convert.ToUInt64(Environment.TickCount)
        Else
            totalTicks = Convert.ToUInt64(Environment.TickCount * -1)
        End If

        Return Math.Abs(totalTicks - lii.dwTime)

    End Function
-1

GetTickCount() , . Abs() , .

Stopwatch .Net QueryPerformanceCounter ++ .

# , . Stopwatch.ElapsedMillseconds .

using System;
using System.Diagnostics;
using System.Windows.Forms;

namespace MiscApp
{
    public partial class Form1 : Form
    {
        private Stopwatch globalTimer = new Stopwatch();
        private long myStamp1 = 0;
        public Form1()
        {
            InitializeComponent();
            globalTimer.Start();
        }

        private void SomeFunction()
        {
            if (globalTimer.ElapsedMilliseconds - myStamp1 >= 3000)
            {
                myStamp1 = globalTimer.ElapsedMilliseconds;
                //Do something here...
            }
        }
    }
}
-1
source

Source: https://habr.com/ru/post/1784487/


All Articles