使用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要快得多。