c#获取系统开机时间

用如下代码获取系统开机时间,获取到的不正确,感觉获取的是上次系统的开机时间,而不是本次的开机时间,

测试了下,电脑开机,马上查看Environment.TickCount值,理论上Environment.TickCount值应该比较小,但实际获取的Environment.TickCount值比较大,感觉得到的是距上次系统开机的时间,而不是本次的,
如果是重启系统,而非关机再开机,那么获取的Environment.TickCount值基本上都是正确的。
请指教下Environment.TickCount究竟是表示什么值,有什么方法可以正确获取系统本次开机的时间?

DateTime dt = DateTime.Now.AddMilliseconds(0 - Environment.TickCount);
Console.WriteLine("开机时间:"+ dt.ToString());

Environment.TickCount表示的是从系统启动以来经过的毫秒数。因此,它在系统开机后的值会随着时间的流逝而增加。如果你在开机后很快查询Environment.TickCount,你可能会得到一个较大的值,因为它包括了开机到查询之间的时间。

如果你想要获取本次系统开机的具体时间,你可以使用其他方法。例如,在Windows系统中,你可以通过读取系统事件日志来获取开机时间。以下是一个示例代码:


using System.Diagnostics;  
  
// 获取系统事件日志  
EventLog systemLog = new EventLog();  
systemLog.Source = "System";  
systemLog.Read EVENT_LOG_TYPE.System;  
  
// 获取开机关联的事件  
EventInstance eventInstance = systemLog.Find(1002);  
  
// 获取事件的时间戳  
long eventTimestamp = eventInstance.TimeCreated.ToFileTime();  
  
// 将时间戳转换为DateTime对象  
DateTime eventDateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(eventTimestamp);  
  
// 输出开机时间  
Console.WriteLine("开机时间: " + eventDateTime.ToString());

这个代码会读取系统事件日志中的开机关联事件,并提取出事件的时间戳。然后,将时间戳转换为DateTime对象,并输出开机时间。请注意,这里使用的是1970年1月1日作为基准时间,以便将时间戳转换为DateTime对象。

需要注意的是,访问系统事件日志需要适当的的管理员权限。如果你没有足够的权限,可能无法成功读取事件日志。

【以下回答由 ChatGPT 生成】

Environment.TickCount返回的是从系统启动到现在所经过的毫秒数,并不是系统本次开机的时间。要获取系统本次开机的时间,可以使用System.Diagnostics命名空间中的Process.StartTime属性。

下面是使用C#获取系统本次开机时间的代码:

using System;
using System.Diagnostics;

class Program
{
    static void Main(string[] args)
    {
        TimeSpan uptime = DateTime.Now - GetLastBootTime();
        Console.WriteLine("本次开机时间:" + uptime.ToString());
    }

    static DateTime GetLastBootTime()
    {
        using (var process = new Process())
        {
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.Arguments = "/c systeminfo | find \"System Boot Time\"";
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.Start();

            string output = process.StandardOutput.ReadToEnd();
            string bootTimeStr = output.Substring(output.IndexOf(':') + 2);
            DateTime bootTime = DateTime.Parse(bootTimeStr);

            process.WaitForExit();

            return bootTime;
        }
    }
}

以上代码中,我们使用System.Diagnostics.Process启动一个命令行进程,执行systeminfo命令,并通过管道过滤出包含"System Boot Time"关键字的行。然后将输出结果解析为DateTime类型的系统开机时间。

需要注意的是,此方法需要使用systeminfo命令,因此要求代码运行在具有足够权限的环境中。

如果不能使用System.Diagnostics.Process获取系统开机时间,我们可以通过使用Windows Management Instrumentation (WMI)查询Win32_OperatingSystem类来获取系统开机时间。以下是使用WMI获取系统开机时间的代码示例:

using System;
using System.Management;

class Program
{
    static void Main(string[] args) 
    {
        TimeSpan uptime = DateTime.Now - GetLastBootTime();
        Console.WriteLine("本次开机时间:" + uptime.ToString());
    }

    static DateTime GetLastBootTime()
    {
        var scope = new ManagementScope("\\\\.\\root\\cimv2");
        var query = new ObjectQuery("SELECT LastBootUpTime FROM Win32_OperatingSystem");

        using (var searcher = new ManagementObjectSearcher(scope, query))
        using (var results = searcher.Get())
        {
            foreach (var item in results)
            {
                var bootTimeStr = item["LastBootUpTime"].ToString();
                var bootTime = ManagementDateTimeConverter.ToDateTime(bootTimeStr);

                return bootTime;
            }
        }

        throw new Exception("Unable to retrieve system boot time.");
    }
}

以上代码使用WMI查询Win32_OperatingSystem类的LastBootUpTime属性,将其转换为DateTime类型的系统开机时间。

这两种方法都可以获取到系统本次开机的时间,选择合适的方法取决于具体的需求和运行环境。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^