如何知道Windows启动或关闭的时间?

时间:2011-09-13 19:23:26

标签: c# windows

我需要在C#中开发一个程序,找出Windows启动或关闭的时间。

是否有我可以阅读的日志文件来了解Windows的启动和关闭时间?或者你有任何想法怎么做?

编辑:

在Reed Copsey先生的帮助下,最佳答案可以在question下找到。

9 个答案:

答案 0 :(得分:15)

根据this article,您可以使用WMI获取上次启动日期/时间

// define a select query
SelectQuery query =
    new SelectQuery(@"SELECT LastBootUpTime FROM Win32_OperatingSystem
       WHERE Primary='true'");

// create a new management object searcher and pass it
// the select query
ManagementObjectSearcher searcher =
    new ManagementObjectSearcher(query);

// get the datetime value and set the local boot
// time variable to contain that value
foreach(ManagementObject mo in searcher.Get())
{
    dtBootTime =
        ManagementDateTimeConverter.ToDateTime(
            mo.Properties["LastBootUpTime"].Value.ToString());

    // display the start time and date
    txtDate.Text = dtBootTime.ToLongDateString();
    txtTime.Text = dtBootTime.ToLongTimeString();
}

答案 1 :(得分:4)

您可以使用System.Diagnostics.Eventing.Reader中的类来访问系统事件日志。

答案 2 :(得分:4)

正如Reed指出的那样,您可以访问事件日志并查看它们的创建时间。 AFAIK没有用于系统启动/关闭的特定事件条目,但您可以查找通常使用Windows启动/停止的服务。虽然使用这种方法意味着它不会100%准确,例如它是否崩溃或手动启动/停止/重新启动。我考虑的一个事件是最准确的是EventLog服务启动/停止事件。

if (EventLog.Exists("System"))
{
    var log = new EventLog("System", Environment.MachineName, "EventLog");

    var entries = new EventLogEntry[log.Entries.Count];
    log.Entries.CopyTo(entries, 0);

    var startupTimes = entries.Where(x => x.InstanceId == 2147489653).Select(x => x.TimeGenerated);
    var shutdownTimes = entries.Where(x => x.InstanceId == 2147489654).Select(x => x.TimeGenerated);
}

修改

原来有一个关机事件。您可以替换Linq来获取它:

var shutdownEvents = entries.Where(x => x.InstanceId == 2147484722);

答案 3 :(得分:3)

您可以使用“系统运行时间”性能计数器来获取开始时间 系统:

 PerformanceCounter systemUpTime = new PerformanceCounter("System", "System Up Time");

 systemUpTime.NextValue();
 TimeSpan upTimeSpan = TimeSpan.FromSeconds(systemUpTime.NextValue());
 Console.Out.WriteLine(DateTime.Now.Subtract(upTimeSpan).ToShortTimeString());

希望,这有帮助。

答案 4 :(得分:3)

使用这段代码可以找到上次重启时间

static void Main(string[] args)
    {          
        TimeSpan t = TimeSpan.FromMilliseconds(System.Environment.TickCount);
        Console.WriteLine( DateTime.Now.Subtract(t));          
    }

答案 5 :(得分:1)

答案 6 :(得分:1)

这里收集了一个可以执行的代码,包括上面的代码。

这是用 .NET 4.6.1 编写的,通常会执行。

您可以选择任何方法:

using System;
using System.Linq;
using System.Diagnostics;
using System.Management;

namespace ConsoleEventLogSample1
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args is null) throw new ArgumentNullException(nameof(args));


            // EventLog
            Console.WriteLine($"EventLog = Last shutdown time : " +
                $"{GetSystemLastTimeByEventLog(false):yyyy-MM-dd HH:MM:ss}, " +
                $"Last startup time : {GetSystemLastTimeByEventLog(true):yyyy-MM-dd HH:MM:ss}"); // ms(fff) is not displayed

            // Registry
            Console.WriteLine($"Registry = Last shutdown time : " +
                $"{GetSystemLastShutdownTimeByRegistry():yyyy-MM-dd HH:MM:ss.fff}");

            // WMI
            Console.WriteLine($"WMI = Last startup time : " +
                $"{GetSystemLastStartupTimeByWMI():yyyy-MM-dd HH:MM:ss.fff}");

            Console.ReadLine();
        }

        static DateTime GetSystemLastTimeByEventLog(bool direction)
        {
            // Do not check for presence or not : Items that must exist
            var log = new EventLog("System", Environment.MachineName, "EventLog");

            var entries = new EventLogEntry[log.Entries.Count];
            log.Entries.CopyTo(entries, 0);

            if (direction)
            {
                return entries.Where(x => x.InstanceId == 2147489653).Select(x => x.TimeGenerated).Last();
            }
            else
            {
                return entries.Where(x => x.InstanceId == 2147489654 || x.InstanceId == 2147489656).Select(x => x.TimeGenerated).Last();
            }
        }

        static DateTime GetSystemLastShutdownTimeByRegistry()
        {
            // Do not check for presence or not : Items that must exist
            string sKey = @"System\CurrentControlSet\Control\Windows";
            using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(sKey))
            {
                string sValueName = "ShutdownTime";
                byte[] val = (byte[])key.GetValue(sValueName);
                long valueAsLong = BitConverter.ToInt64(val, 0);
                return DateTime.FromFileTime(valueAsLong);
            }
        }

        static DateTime GetSystemLastStartupTimeByWMI()
        {
            // Do not check for presence or not : Items that must exist
            SelectQuery query = new SelectQuery(@"select LastBootUpTime from Win32_OperatingSystem where Primary='true'");

            ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
            DateTime lastdt = new DateTime();

            foreach (ManagementObject mo in searcher.Get())
            {
                lastdt = ManagementDateTimeConverter.ToDateTime(mo.Properties["LastBootUpTime"].Value.ToString());
                break;
            }

            return lastdt;
        }

    }
}

答案 7 :(得分:0)

System.Environment.TickCount有24.8天的限制 这是因为TickCount是有符号32位值中包含的毫秒值。

Windows API公开了这两个功能:
GetTickCount - 返回32位值 - 可从Windows 2000获得 GetTickCount64 - 返回64位值 - 可从Vista / Windows Server 2008

获得

您可以这样使用GetTickCount64:

using System.Runtime.InteropServices;  

[DllImport("Kernel32.dll")]  
static extern long GetTickCount64();  

DateTime osStartTime = DateTime.Now - new TimeSpan(10000 * GetTickCount64());

答案 8 :(得分:0)

URL"imageDownloadURL" : URL! 中,您可以使用full sheet属性。

.NET 5