C#を使用してシステムの稼働時間を取得する簡単な方法はありますか?
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());
}
}
}
私は少し遅れていますが、別のsimple方法は GetTickCount64 関数を使用することです。これはWindows Vista以降で利用可能ですGetTickCountのようにオーバーフローしません。
public static TimeSpan GetUpTime()
{
return TimeSpan.FromMilliseconds(GetTickCount64());
}
[DllImport("kernel32")]
extern static UInt64 GetTickCount64();
System.Environment.TickCount は、システムが再起動されてからのミリ秒数を取得します。
ただし、Int32であり、24.9日後にオーバーフローし、マイナスになることに注意してください。 MDSNドキュメントの備考を参照してください。
タスクマネージャーによると、マシンのアップタイムは58 days 17 hours
です。私はここで各回答を試してみましたが、高速な回答は少し離れています(おおよそ1〜3分ですが、58日以上の稼働時間)。
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
最後の2つ(PerformanceCounterを使用するかManagementObjectを使用する)は、常にWindowsタスクマネージャーと同じ秒以内です(Wordを使用するか、以下のコードを使用して自分で試してください)。結果に基づいて、ManagementObject LastBootUpTime
メソッドを使用します。これは、PerformanceCounter
よりも大幅に高速ですが、タスクマネージャーと比較すると完全に正確であるためです。
時間を出力する前に各メソッドから現在の経過時間を差し引いたが、実行するのに2秒未満しかかからないため、実行時間を不適切に計算してもタイムシフトを説明できないことに注意してください。私が使用したコードは次のとおりです。
[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}");
}
正確かつ大きいSystem.Environment.TickCount
、OSの恐ろしいパフォーマンスカウンター、WMIまたはネイティブコールは含まれません。
var ticks = Stopwatch.GetTimestamp();
var uptime = ((double)ticks) / Stopwatch.Frequency;
var uptimeSpan = TimeSpan.FromSeconds(uptime);
これを行う最も簡単で適切な方法は
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();
}
シンプルですが、できます:
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!");
}
私は質問が古くて解決されていることを知っていますが、私ができる最も簡単な解決策は、Enviroment.TickCountプロパティを使用することです。これは、システムが開始されてからのミリ秒数を返します。
System.DateTime SystemStartTime = DateAndTime.Now.AddMilliseconds(-Environment.TickCount);
System.DateTime Uptime = DateAndTime.Now - SystemStartTime;
このソリションは、受け入れられているアンスウェアよりもはるかに高速です。