.net - Hent system oppetid ved hjælp af C #

Indlæg af Hanne Mølgaard Plasc

Problem



Er der en simpel måde at få et systems oppetid på med C #?

Bedste reference


public TimeSpan UpTime {
    get {
        using (var uptime = new PerformanceCounter("System", "System Up Time")) {
            uptime.NextValue();       //Call this an extra time before reading its value
            return TimeSpan.FromSeconds(uptime.NextValue());
        }
    }
}

Andre referencer 1


Jeg er lidt sent, men en anden simpel måde er at bruge GetTickCount64-funktionen, som er tilgængelig fra og med Windows Vista og overlader ikke som GetTickCount gør: [13]


public static TimeSpan GetUpTime()
{
    return TimeSpan.FromMilliseconds(GetTickCount64());
}

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

Andre referencer 2


System.Environment.TickCount får antallet af millisekunder, siden systemet blev genstartet. [14]


Pas på, at det er en Int32 og vil overflyde efter 24,9 dage og bliver negativ. Se bemærkningerne på MDSN-dokumenterne.

Andre referencer 3


Maskinen har en oppetid på 58 days 17 hours i henhold til Task Manager. Jeg gik igennem og prøvede hvert svar her, og de hurtige er slukket af en lille smule (~ 1-3 minutter stort set, men over 58 dages oppetid):


Stopwatch.GetTimeStamp(): 58days 17hours 11minutes 25seconds ~Time to calculate (ms): 6.8413 DllImport GetTickCount64(): 58days 17hours 13minutes 34seconds ~Time to calculate (ms): 0.2192 PerformanceCounter(System, System Up Time): 58days 17hours 14minutes 02seconds ~Time to calculate (ms): 1233.2854 ManagementObject LastBootUpTime: 58days 17hours 14minutes 02seconds ~Time to calculate (ms): 30.0283


De sidste to, der bruger PerformanceCounter eller bruger ManagementObject, er altid inden for samme sekund som Windows Task Manager (skal bare tage mit ord til det eller prøve det selv med koden nedenfor). Baseret på resultaterne skal jeg bruge ManagementObject LastBootUpTime metoden, fordi den er drastisk hurtigere end PerformanceCounter, men er stadig helt nøjagtig i forhold til Task Manager.


Bemærk, at jeg trukket den nuværende forløbet tid fra hver metode, før du udskriver tiderne, men det hele tager mindre end 2 sekunder at køre, så tidsskiftet kan ikke forklares ved at fejlagtigt regne med henrettelsestid alligevel. Her er koden Jeg brugte:


[System.Runtime.InteropServices.DllImport("kernel32")]
extern static UInt64 GetTickCount64();

public static void Main()
{
    var start = Stopwatch.StartNew();

    var eachStart = Stopwatch.StartNew();
    var ticks = Stopwatch.GetTimestamp();
    var uptime = ((double)ticks) / Stopwatch.Frequency;
    var uptimeTimeSpan = TimeSpan.FromSeconds(uptime);
    Console.WriteLine("Stopwatch.GetTimeStamp():                   " + uptimeTimeSpan.Subtract(start.Elapsed).ToString(@"dddays hhhou
s mmmi
u	es ssseco
ds"));
    Console.WriteLine($"~Time to calculate (ms): {eachStart.Elapsed.TotalMilliseconds}");

    eachStart.Restart();
    Console.WriteLine("DllImport GetTickCount64():                 " + TimeSpan.FromMilliseconds(GetTickCount64()).Subtract(start.Elapsed).ToString(@"dddays hhhou
s mmmi
u	es ssseco
ds"));
    Console.WriteLine($"~Time to calculate (ms): {eachStart.Elapsed.TotalMilliseconds}");

    eachStart.Restart();
    var upTime = new PerformanceCounter("System", "System Up Time");
    upTime.NextValue();       //Call this an extra time before reading its value
    Console.WriteLine("PerformanceCounter(System, System Up Time): " + TimeSpan.FromSeconds(upTime.NextValue()).Subtract(start.Elapsed).ToString(@"dddays hhhou
s mmmi
u	es ssseco
ds"));
    Console.WriteLine($"~Time to calculate (ms): {eachStart.Elapsed.TotalMilliseconds}");

    eachStart.Restart();
    ManagementObject mo = new ManagementObject(@"\.
ootcimv2:Win32\_OperatingSystem=@");
    DateTime lastBootUp = ManagementDateTimeConverter.ToDateTime(mo["LastBootUpTime"].ToString());
    Console.WriteLine("ManagementObject LastBootUpTime:            " + (DateTime.Now.ToUniversalTime() - lastBootUp.ToUniversalTime()).Subtract(start.Elapsed).ToString(@"dddays hhhou
s mmmi
u	es ssseco
ds"));
    Console.WriteLine($"~Time to calculate (ms): {eachStart.Elapsed.TotalMilliseconds}");
}

Andre referencer 4


Præcis og større end System.Environment.TickCount, der ikke involverer OS forfærdelige PER-tællere, WMI eller indgående opkald:


var ticks = Stopwatch.GetTimestamp();
var uptime = ((double)ticks) / Stopwatch.Frequency;
var uptimeSpan = TimeSpan.FromSeconds(uptime);

Andre referencer 5


Den enkleste og rigtige måde at gøre dette på er


public static TimeSpan GetUptime()
{
    ManagementObject mo = new ManagementObject(@"\.
ootcimv2:Win32\_OperatingSystem=@");
    DateTime lastBootUp = ManagementDateTimeConverter.ToDateTime(mo["LastBootUpTime"].ToString());
    return DateTime.Now.ToUniversalTime() - lastBootUp.ToUniversalTime();
}

Andre referencer 6


Enkelt, nej, men det kan gøres:


    static DateTime getLastBootTime(ManagementObject mObject)
    {
        PropertyData pd = mObject.Properties["LastBootUpTime"];
        string name = pd.Name.ToString();
        DateTime lastBoot = parseCmiDateTime(pd.Value.ToString());
        return lastBoot;
    }

    static ManagementObject getServerOSObject(string serverName)
    {
        ManagementObjectSearcher mSearcher = new ManagementObjectSearcher("Select * From Win32\_OperatingSystem");
        mSearcher.Scope = new ManagementScope(String.Format(@"\{0}
ootcimv2", serverName));
        ManagementObjectCollection mObjects = mSearcher.Get();
        if (mObjects.Count != 1) throw new Exception(String.Format("Expected 1 object, returned {0}.", mObjects.Count));
        foreach (ManagementObject m in mObjects)
        {
            //No indexing on collection
            return m;
        }
        throw new Exception("Something went wrong!");
    }

Andre referencer 7


Jeg ved, at spørgsmålet er både gammelt og løst, men den bedste løsning, jeg kan tænke på, bruger bare egenskaben Enviroment.TickCount, som returnerer antallet af millisekunder siden systemet startede:


System.DateTime SystemStartTime = DateAndTime.Now.AddMilliseconds(-Environment.TickCount);
System.DateTime Uptime = DateAndTime.Now - SystemStartTime;


Denne opgave er meget hurtigere end den accepterede answare.