使用C#检索系统正常运行时间

Pro*_*ope 58 .net c# windows uptime

有没有一种简单的方法可以使用C#获得系统的正常运行时间?

SLa*_*aks 54

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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果计数器名称已本地化怎么办 (7认同)
  • 使用以下命令获取本地化名称(2 = System,674 = System Up Time):`StringBuilder buffer = new StringBuilder(1024); uint buf_size =(uint)buffer.Capacity; Win32.PdhLookupPerfNameByIndex(null,id,buffer,ref buf_size); return buffer.ToString();` (3认同)
  • 第一次调用uptime.NextValue将返回0. (2认同)
  • 我反对这是“一种简单的方法”。最重要的是,尝试在 *nix 上运行它。 (2认同)

Mar*_*tin 39

我有点迟了,但另一个简单的方法是使用GetTickCount64函数,该函数从Windows Vista开始可用,并且不会像GetTickCount那样溢出:

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

[DllImport("kernel32")]
extern static UInt64 GetTickCount64();
Run Code Online (Sandbox Code Playgroud)

  • `GetTickCount64 ...没有溢出` - 当他们找到一种让我的代码运行5850亿年的方法时它会溢出 (8认同)
  • 在最新的 .NET 版本中无需使用 P/Invoke,因为 **Environment** 类现在具有 [`TickCount64` 属性](https://docs.microsoft.com/en-us/dotnet /api/system.environment.tickcount64?view=net-5.0)。 (4认同)
  • @rkagerer,等等看。像那些短视的假设把我们带到了 y2k 和 2038 年的纪元结束 =D (2认同)

adr*_*nks 26

System.Environment.TickCount获取自系统重新启动以来的毫秒数.

请注意,它是一个Int32,并将在24.9天后溢出并将变为负数.请参阅MDSN文档上的备注.

  • 或者,更好的是,调用TimeSpan.FromMilliseconds (4认同)
  • 令人困惑的是,Environment.TickCount返回的毫秒数,而不是.Net ticks(A .Net tick为100纳秒). (3认同)
  • 要从中获得大约 49.7 天的连续性,只需将其转换为“UInt32”/“uint”。 (3认同)
  • 如果你真的只想要正常运行时间,这不是一个更快更好的答案吗? (3认同)
  • 在最新的 .NET 版本中,**Environment** 类具有 [`TickCount64` 属性](https://learn.microsoft.com/en-us/dotnet/api/system.environment.tickcount64?view=net -5.0),这避免了环绕问题。 (3认同)

Qua*_*tic 19

58 days 17 hours根据任务管理器,我的机器有正常运行时间.我经历过并尝试了每个答案,快速的一点点关闭(约1-3分钟,但超过58天的正常运行时间):

ManagementObject LastBootUpTime

最后两个,使用PerformanceCounter或使用ManagementObject,始终与Windows任务管理器在同一秒内(只需要接受我的话,或者使用下面的代码自己尝试).根据结果​​,我将使用该PerformanceCounter方法,因为它比58 days 17 hours任务管理器快得多,但仍然完全准确.

请注意,我确实在打印时间之前减去了每个方法的当前经过时间,但是整个过程运行时间不到2秒,因此无法通过不正确地计算执行时间来解释时移.这是我使用的代码:

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
Run Code Online (Sandbox Code Playgroud)


Ste*_*nds 13

如果您使用更高版本的 .NET(Core 3.0/.NET 5.0 或更高版本),则该类Environment现在具有TickCount64 属性

这不会受到属性的环绕问题的影响TickCount,您也不必求助于 P/Invoke 来获取值。

long tickCountMs = Environment.TickCount64;
var uptime = TimeSpan.FromMilliseconds(tickCountMs);
Run Code Online (Sandbox Code Playgroud)


Rbj*_*bjz 11

精确和大于System.Environment.TickCount,不涉及OS可怕的性能计数器,WMI或本机调用:

var ticks = Stopwatch.GetTimestamp();
var uptime = ((double)ticks) / Stopwatch.Frequency;
var uptimeSpan = TimeSpan.FromSeconds(uptime);
Run Code Online (Sandbox Code Playgroud)

  • [获取高分辨率时间戳](http://msdn.microsoft.com/en-us/library/windows/desktop/dn553408%28v=vs.85%29.aspx) 解释了为什么返回正常运行时间:“QueryPerformanceCounter [...] 返回自 Windows 操作系统启动以来发生的滴答总数,包括计算机处于睡眠状态(例如待机、休眠或连接待机)的时间。 (2认同)

小智 7

最简单和正确的方法是

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();
}
Run Code Online (Sandbox Code Playgroud)

  • 如果在 *nix 上运行,这会让你很开心 (2认同)