使用C#检索系统正常运行时间
有一个简单的方法来获得系统的正常运行时间使用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()); } } }
我有点晚了,但另一个简单的方法是使用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文档上的注释。
根据任务pipe理器,我的机器有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
最后两个,使用PerformanceCounter或使用ManagementObject,总是在Windows任务pipe理器(只需要听我的话,或自己尝试下面的代码)相同的秒钟。 基于结果,我将使用ManagementObject LastBootUpTime
方法,因为它比PerformanceCounter
速度快得多,但与任务pipe理器相比仍然非常准确。
请注意,在打印时间之前,我已经从每种方法中减去了当前stream逝的时间,但是整个事情的运行时间不到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!"); }
我知道问题既旧又解决,但是我可以使用的最恶劣的解决scheme是使用Enviroment.TickCount属性,它返回自系统启动以来的毫秒数。
System.DateTime SystemStartTime = DateAndTime.Now.AddMilliseconds(-Environment.TickCount); System.DateTime Uptime = DateAndTime.Now - SystemStartTime;
这个独奏比接受的answare要快得多。