使用 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 ;
}
我尽可能使用空格和分号来让我更清楚。
你好,我有一个监控脚本(带有 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 ;
}
我尽可能使用空格和分号来让我更清楚。