如何知道何时启动或关闭Windows

本文关键字:Windows 启动 何知道 何时 | 更新日期: 2023-09-27 18:08:34

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

是否有一个日志文件,我可以读知道Windows启动和关闭时间?或者你有什么想法吗?

编辑:

在Reed Copsey先生的帮助下,找到了这个问题的最佳答案。

如何知道何时启动或关闭Windows

根据本文,您可以使用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();
}

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());

正如Reed指出的,您可以访问事件日志并查看它们是何时创建的。据我所知,没有特定的系统启动/关闭事件条目,但您可以查找通常与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);

您可以使用system . diagnostics . events . reader中的类来访问系统事件日志。

您可以使用"System Up Time"性能计数器来获取系统的开始时间系统:

 PerformanceCounter systemUpTime = new PerformanceCounter("System", "System Up Time");
 systemUpTime.NextValue();
 TimeSpan upTimeSpan = TimeSpan.FromSeconds(systemUpTime.NextValue());
 Console.Out.WriteLine(DateTime.Now.Subtract(upTimeSpan).ToShortTimeString());

希望有帮助。

最后一次重启时间可以使用这段代码找到

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

更多选项:

  • 使用。net
  • 获取上次windows关机事件的日期时间
  • http://www.codeproject.com/KB/cs/GetLastRebootTime.aspx

下面是可以执行的收集代码,包括上面的代码。

这是在。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;
        }
    }
}

.NET 5.NET Core 3中,您可以使用环境。TickCount64财产。

var t = TimeSpan.FromMilliseconds(Environment.TickCount64);
var lastBootTime = DateTime.UtcNow.Subtract(t);
Console.WriteLine(lastBootTime);