Frage

Ich möchte auf wissen, wann war das letzte Mal das System gestartet wurde.

Environment.TickCount wird funktionieren, aber es bricht nach 48-49 Tagen wegen der Begrenzung der int.

Dies ist der Code, den ich habe mit:

Environment.TickCount & Int32.MaxValue

Hat jemand weiß, über lange Art Rückkehr irgendwie?

Ich verwende diese die Leerlaufzeit des Systems zu kennen:

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;
}
War es hilfreich?

Lösung

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());
    }
}

Andere Tipps

Sie sind richtig, dass Environment.TickCount wird nach ca. 25 Tagen überlaufen, weil der Rückgabewert ist ein 32-Bit-Integer.

Aber es gibt einen besseren Weg, als zu versuchen, die TickCount zu vergleichen, wenn Sie bestimmen wollen, wenn das System zuletzt gestartet wurde. Was Sie suchen ist die System up-time genannt. Es gibt ein paar verschiedene Möglichkeiten, dass Sie diese abrufen können.

Der einfachste Weg ist die PerformanceCounter Klasse verwenden (im System.Diagnostics Namespace), die Sie Zähler abfragen, um eine bestimmte Systemleistung ermöglicht. Versuchen Sie, den folgenden Code:

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());

Alternativ können Sie tun dies durch WMI . Aber es sieht aus wie stian.net Antwort dass gelegt hat.

Beachten Sie schließlich, dass der Name des Leistungsindikatoren muss lokalisiert werden, wenn Sie internationale Versionen von Windows unterstützen müssen, damit die richtige Lösung muss die lokalisierten Strings für „System“ suchen und „System Up Time“ mit PdhLookupPerfNameByIndex , oder Sie müssen sicherstellen, dass Sie die PdhAddEnglishCounter unter der Motorhaube, die in nur unterstützt, Vista oder höher. Mehr über dieses hier .

Der folgende Code ruft die Millisekunden seit dem Systemstart (Aufruf unmanged API). Ich maß die Leistungskosten für den Interop-Betrieb, und es ist ziemlich identisch mit Stoppuhr () (aber das Abrufen nicht die Zeit seit dem System direkt natürlich starten).

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

Wenn Sie jede Wraparound zählen, können Sie Ihre eigenen 64-Bit-Tickcount, gut für 2 ^ 63 ms (292.000.000 Jahre) oder 2 ^ 64 ms (585.000.000 Jahre) machen. Wenn Sie nicht die volle 1ms Präzision brauchen (eigentlich nur 10-16ms Auflösung) oder einen Bereich, können Sie das Ergebnis von 1000 teilen und zu 49.710 Tagen repräsentieren bis (136 Jahre), mit einer Auflösung von einer Sekunde in einem UInt32.

GetTickCount64() tut dies für Sie, aber ist nur in Vista oder höher.

Hier zähle ich die wraparounds der verstrichenen Zeit, nicht 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 );
}

Verknüpfung mit Int32.MaxValue ist unnötig und ein schlechtes Beispiel in der .NET-Dokumentation. Ungeprüfter Subtraktion von 32-Bit-Integer Überlauf sicher. Das Zeichen der Environment.TickCount zählt nie. Subtraction Griffe alle Fälle, die Wrap-around. Beispiel wraparound von einem: uiT0 = Int32.MaxValue; iTickNow = uiT0 + 1 Ausbeute Int32.MinValue; schließlich. (iTickNow - uiT0) ergibt 1

uiElapsed Spuren verstrichene Zeit den ganzen Weg auf 49,7 Tage, bevor es auf Null hüllt. Jedes Mal, es wickelt, wird iWrapCount erhöht. GetElapsedTime () muss mindestens einmal alle 49,7 Tage genannt werden, so dass kein Wraparound unentdeckt.

Ich denke, es ist nur die Art, wie sie es umgesetzt haben.

Es geht von 0 bis max und geht dann von min auf 0.

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

ich bearbeitet habe den Code Sie verwenden, von http://www.codeproject.com/Articles/13384/Getting-the-user-idle-time-with-C

Warum Sie nicht nur die absolute Nummer?

    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

Ich bin kein Fan von mit GetTickCount () für Zeitstempel, da kann es negative Zahlen zurück. Auch wenn mit Abs () kann helfen, aber es ist umständlich und keine optimale Lösung.

Es ist besser, zu verwenden Stoppuhr in .Net oder Queryperformancecounter in C ++ als Zeitstempel.

Innerhalb einer C # -Anwendung, ich ein globales Stoppuhr Objekt, es starten. Später in der Anwendung, verwende ich die Stopwatch.ElapsedMiliseconds als Zeitstempel.

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...
            }
        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top