我需要在C#中开发一个程序,找出Windows启动或关闭的时间。
是否有我可以阅读的日志文件来了解Windows的启动和关闭时间?或者你有任何想法怎么做?
编辑:
在Reed Copsey先生的帮助下,最佳答案可以在question下找到。
答案 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)