windows 关机重启
一 windows 关机重启流程
1 用户请求关机:
用户通过开始菜单、快捷键(如Alt+F4),或其他手段(如命令行)发起关机请求。
2 通知应用程序:
Windows向所有运行中的应用程序发送WM_QUERYENDSESSION消息。这是一个通知,告知应用程序系统即将关闭。
https://learn.microsoft.com/zh-cn/windows/win32/shutdown/wm-queryendsession
应用程序应保存数据并清理资源。如果需要,应用程序可以请求取消关机(尽管用户可以决定强制关机)。
3 确认关机意图:
用户有机会通过对话框确认或取消关机请求。
4 终止应用程序:
Windows向所有应用程序发送WM_ENDSESSION消息。应用程序必须保存未完成的工作并关闭。
在一段时间后,Windows强制关闭未响应的应用程序,不过这可能导致数据丢失。
5 关闭用户会话:
关闭所有用户会话,释放用户相关资源。
用户配置和设置会被保存。
6停止服务:
Windows开始逐步停止系统服务。
大多数后台服务在其他用户进程之前被告知关闭。
7 卷影复制/存储快照:
如果启用,Windows会处理卷影复制,以确保磁盘的一致状态。
断开网络连接:
关闭所有网络连接,包括网络共享和远程存取。
8 写入系统日志:
Windows将关机事件记录到事件日志中,包括原因和时间。
9 关闭设备驱动程序:
按照与骚扰硬件的顺序,关闭设备驱动程序。
设备驱动程序完成所有未完成的I/O操作并释放硬件资源。
10 电源管理逻辑:
操作系统通过ACPI与系统固件交互,准备进入关机状态。
Windows指示固件关闭所有系统电源。
11 电源关闭:
在最底层,最后的电源信号被传递,计算机完全断电。
二 区分windows系统重启\关机
从《windows 关机重启流程》得知windows 消息无法区分重启\关机,只能通过系统user32 日志判断了
1 基于Topshelf 配置HostConfigurator
hostConfig.EnableShutdown();hostConfig.EnableSessionChanged();
2 实现 ConfigService
public void ConfigService(ServiceConfigurator<IService> serviceConfig){serviceConfig.WhenShutdown(Shutdown);serviceConfig.WhenSessionChanged((service, session) =>{WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();switch (session.ReasonCode){case SessionChangeReasonCode.SessionLogoff:_shutdownRebootService.Watcher();break;}});
3 实现Shutdown
private async void Shutdown(IService service, HostControl control){Log.Info("=======>>系统即将关闭.....");var systemPowerCycle = _shutdownRebootService.GetSystemPowerCycle();ServiceCenters.Log.Info($"当前系统电源状态:{systemPowerCycle}");// 获取到重启、关机状态}
4 ShutdownRebootService 重启关机具体实现类
internal class ShutdownRebootService
{/// <summary>/// 监听重启关机系统事件/// </summary>public void Watcher(){Task.Run(() =>{try{var systemEventLog = new EventLog("System");EventLogEntry latestUser32Entry = null;var entries = systemEventLog.Entries;for (int i = entries.Count; i > 0; i--){var entry = entries[i - 1];if (string.Equals(entry.Source, "USER32", StringComparison.OrdinalIgnoreCase) && entry.EventID == 1074){latestUser32Entry = entry;break;}}if (latestUser32Entry != null){logger.Info($"命令来源:{latestUser32Entry.ReplacementStrings[0]}");logger.Info($"原因:{latestUser32Entry.ReplacementStrings[2]}");logger.Info($"原因代码:{latestUser32Entry.ReplacementStrings[3]}");logger.Info($"关机类型:{latestUser32Entry.ReplacementStrings[4]}");logger.Info($"记录时间:{latestUser32Entry.TimeGenerated}");_state = latestUser32Entry.ReplacementStrings[4];}logger.Info($"完成主动查询系统(重启、开机)");}catch (Exception e){logger.Error($"主动查询系统(重启、开机)异常:{e}");}});}/// <summary>/// 获取电源循环(包括关机和重新启动)/// </summary>/// <returns></returns>public SystemPowerCycle GetSystemPowerCycle(){ // 使用正则表达式检查状态字符串if (System.Text.RegularExpressions.Regex.IsMatch(_state, @"(?i)(重启|restart)")){return SystemPowerCycle.Reboot;}if (System.Text.RegularExpressions.Regex.IsMatch(_state, @"(?i)(关闭电源|power\s+off)")){return SystemPowerCycle.Shutdown;}return SystemPowerCycle.Unknown;}private string _state = string.Empty;private SystemPowerCycle _systemPowerCycle = SystemPowerCycle.Unknown;
}