You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PowerShell拦截Windows关机信号并在关机前执行写入操作

PowerShell拦截Windows关机信号并执行预设写入操作实现方案

实现原理

Windows发起关机、重启、注销流程时,会向所有顶层窗口广播WM_QUERYENDSESSION系统消息,同时会触发WMI系统事件。你可以通过PowerShell监听上述两类通知,在系统执行关机动作前运行自定义写入逻辑。

实现方案

方案1:WMI事件监听(简单易用,适合轻量写入操作)

无需引入额外依赖,直接注册系统级事件监听即可实现:

  1. 首先定义你需要执行的写入逻辑,示例为写入关机日志到本地文件:
function Invoke-PreShutdownTask {
    # 替换为你自己的写入逻辑,支持写入文件、注册表、数据库等任意操作
    $log = "关机操作触发时间:$([DateTime]::Now.ToString('yyyy-MM-dd HH:mm:ss'))"
    $log | Out-File -Path "C:\ShutdownRecord.log" -Append -Encoding UTF8
}
  1. 注册关机事件监听,事件触发时自动执行写入操作:
# 注册系统关机/重启/注销事件查询
$shutdownQuery = "SELECT * FROM Win32_ComputerShutdownEvent"
Register-WmiEvent -Query $shutdownQuery -Action {
    Invoke-PreShutdownTask
} | Out-Null

# 防止脚本进程自动退出,保持后台监听
while ($true) {
    Start-Sleep -Seconds 30
}

方案2:WinForm消息监听(稳定可靠,适合耗时写入操作)

如果你的写入操作耗时较长,建议使用该方案,系统会默认等待消息处理完成再推进关机流程,无需主动取消关机:

Add-Type -AssemblyName System.Windows.Forms

# 定义写入逻辑
function Invoke-PreShutdownTask {
    $log = "关机操作触发时间:$([DateTime]::Now.ToString('yyyy-MM-dd HH:mm:ss'))"
    $log | Out-File -Path "C:\ShutdownRecord.log" -Append -Encoding UTF8
    # 模拟耗时操作,可根据实际场景调整
    Start-Sleep -Seconds 10
}

# 创建隐藏窗口用于接收系统消息
$hiddenForm = New-Object System.Windows.Forms.Form
$hiddenForm.Visible = $false
$hiddenForm.ShowInTaskbar = $false

# 绑定系统关闭事件处理逻辑
$hiddenForm.Add_Closing({
    param($sender, $eventArgs)
    # 仅处理系统关机触发的关闭请求
    if ($eventArgs.CloseReason -eq [System.Windows.Forms.CloseReason]::WindowsShutDown) {
        # 先执行写入操作
        Invoke-PreShutdownTask
    }
})

# 启动消息循环保持监听
[System.Windows.Forms.Application]::Run($hiddenForm)

注意事项

  • 所有脚本必须以管理员权限运行,否则无法注册系统级事件、也无法读取关机事件通知
  • 写入操作的目标路径需要确保运行脚本的账号有对应读写权限,避免操作失败
  • 如需长期生效,可将脚本添加到Windows任务计划程序,设置开机自动以管理员权限启动
  • 如果写入操作耗时超过10秒,建议优先使用方案2,避免被系统强制终止进程导致写入不完整

内容的提问来源于stack exchange,提问作者Andrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 19:15:02