web-dev-qa-db-fra.com

Récupérer la disponibilité du système à l'aide de C #

Existe-t-il un moyen simple d'obtenir la disponibilité d'un système en utilisant C #?

55
ProgrammingPope
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());
        }
    }
}
52
SLaks

Je suis un peu en retard, mais une autre manière simple consiste à utiliser la fonction GetTickCount64 , disponible à partir de Windows Vista et ne déborde pas comme le fait GetTickCount:

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

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

System.Environment.TickCount obtient le nombre de millisecondes depuis le redémarrage du système.

Attention cependant, il s'agit d'un Int32 qui débordera après 24,9 jours et deviendra négatif. Voir les remarques sur les documents MDSN.

26
adrianbanks

Ma machine a une disponibilité de 58 days 17 hours selon le Gestionnaire des tâches. J'ai parcouru et essayé chaque réponse ici et les réponses rapides sont légèrement décalées (~ 1-3 minutes environ, mais plus de 58 jours de disponibilité):

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

Les deux derniers, à l'aide de PerformanceCounter ou à l'aide de ManagementObject, sont toujours dans la même seconde que le Gestionnaire des tâches de Windows (il suffit de prendre mon Word pour lui, ou de l'essayer vous-même avec le code ci-dessous). Sur la base des résultats, je vais utiliser le ManagementObject LastBootUpTime car il est considérablement plus rapide que le PerformanceCounter mais est toujours parfaitement précis par rapport au Gestionnaire des tâches.

Notez que j'ai soustrait le temps écoulé actuel de chaque méthode avant d'imprimer les temps, mais le tout prend moins de 2 secondes pour s'exécuter, le décalage temporel ne peut donc pas être expliqué par une comptabilisation incorrecte du temps d'exécution de toute façon. Voici le code que j'ai utilisé:

[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(@"dd\d\a\y\s\ hh\h\o\u\r\s\ mm\m\i\n\u\t\e\s\ ss\s\e\c\o\n\d\s"));
    Console.WriteLine($"~Time to calculate (ms): {eachStart.Elapsed.TotalMilliseconds}");

    eachStart.Restart();
    Console.WriteLine("DllImport GetTickCount64():                 " + TimeSpan.FromMilliseconds(GetTickCount64()).Subtract(start.Elapsed).ToString(@"dd\d\a\y\s\ hh\h\o\u\r\s\ mm\m\i\n\u\t\e\s\ ss\s\e\c\o\n\d\s"));
    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(@"dd\d\a\y\s\ hh\h\o\u\r\s\ mm\m\i\n\u\t\e\s\ ss\s\e\c\o\n\d\s"));
    Console.WriteLine($"~Time to calculate (ms): {eachStart.Elapsed.TotalMilliseconds}");

    eachStart.Restart();
    ManagementObject mo = new ManagementObject(@"\\.\root\cimv2:Win32_OperatingSystem=@");
    DateTime lastBootUp = ManagementDateTimeConverter.ToDateTime(mo["LastBootUpTime"].ToString());
    Console.WriteLine("ManagementObject LastBootUpTime:            " + (DateTime.Now.ToUniversalTime() - lastBootUp.ToUniversalTime()).Subtract(start.Elapsed).ToString(@"dd\d\a\y\s\ hh\h\o\u\r\s\ mm\m\i\n\u\t\e\s\ ss\s\e\c\o\n\d\s"));
    Console.WriteLine($"~Time to calculate (ms): {eachStart.Elapsed.TotalMilliseconds}");
}
18
Quantic

Précis et plus grand que System.Environment.TickCount, n'impliquant pas d'horribles compteurs de performances OS, WMI ou appels natifs:

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

La façon la plus simple et appropriée de le faire est

public static TimeSpan GetUptime()
{
    ManagementObject mo = new ManagementObject(@"\\.\root\cimv2:Win32_OperatingSystem=@");
    DateTime lastBootUp = ManagementDateTimeConverter.ToDateTime(mo["LastBootUpTime"].ToString());
    return DateTime.Now.ToUniversalTime() - lastBootUp.ToUniversalTime();
}
7
Jakub Chodounsky

Simple, non mais cela peut se faire:

    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}\root\cimv2", 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!");
    }
4
C. Ross

Je sais que la question est à la fois ancienne et résolue, mais la solution la plus simple à laquelle je peux penser est simplement d'utiliser la propriété Enviroment.TickCount, qui renvoie le nombre de millisecondes depuis le démarrage du système:

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

Cette solution est beaucoup plus rapide que les réponses acceptées.

1
BlackCap