使用 Powershell 检测系统关闭

Detect System Shutdown with Powershell

你好,我有一个监控脚本(带有 winforms gui),它总是在后面 运行。 不幸的是,当用户尝试手动关闭计算机时,这会惹恼他们,因为它会引发“此应用程序正在阻止 windows 关机”屏幕。

所以我需要一种可靠的方法来在启动关机时自动关闭脚本。

我尝试订阅 SessionEnding- 和 SessionEnded 事件,但没有成功:

$sysevent = [microsoft.win32.systemevents]
Register-ObjectEvent -InputObject $sysevent -EventName "SessionEnding" -Action { Exitfunction }

更新: 目前是这样的:

$sysevent = [microsoft.win32.systemevents]
Register-ObjectEvent -InputObject $sysevent -EventName "SessionEnding" -Action { [Windows.Forms.MessageBox]::Show("Shutdown!", "", [Windows.Forms.MessageBoxButtons]::OK, [Windows.Forms.MessageBoxIcon]::Warning)}
Register-ObjectEvent -InputObject $sysevent -EventName "SessionEnded" -Action { [Windows.Forms.MessageBox]::Show("Shutdown!", "", [Windows.Forms.MessageBoxButtons]::OK, [Windows.Forms.MessageBoxIcon]::Warning)}
Register-WmiEvent -Class win32_computerShutdownEvent -Action { [Windows.Forms.MessageBox]::Show("Shutdown!", "", [Windows.Forms.MessageBoxButtons]::OK, [Windows.Forms.MessageBoxIcon]::Warning)}

我添加了一个消息框来查看这些事件中的一个是否真的会触发,但动作脚本块执行的代码可能有问题。没有运气。 None 这些事件在我尝试关闭 windows 8.1 系统时启动 。 当我使用 get-job 读取事件时,没有错误。状态都在"not started".

知道为什么吗?

你看过这篇文章了吗?

http://blogs.technet.com/b/heyscriptingguy/archive/2010/04/15/hey-scripting-guy-april-15-2010.aspx

他使用 wmi 来观看事件 Register-WmiEvent -Class win32_computerShutdownEvent

好的解决方案是:如果启动关机,Windows 向所有应用程序发送 WM_QUIT-Message。如果您订阅 onClosing 事件,则可以查询 $eventargs 事件是否已触发。它包含一个 CloseReason-属性,如果它是 WindowsShutdown,则可用于启动适当的清理并关闭应用程序。 有关如何执行此操作的更多信息,请参阅此 post 的答案。

以下代码不是您完整问题的答案,但它是您标题问题的答案,可能会帮助那些只想停止已经超时的关机的人:

If ( [ System.Environment ]:: HasShutdownStarted ) {
  & "$env:SystemRoot\System32\Shutdown.exe" -a ;
}

我尽可能使用空格和分号来让我更清楚。