在 Powershell 中优雅地停止
Posted
技术标签:
【中文标题】在 Powershell 中优雅地停止【英文标题】:Gracefully stopping in Powershell 【发布时间】:2010-12-15 04:56:08 【问题描述】:如何在 PowerShell 脚本中捕获和处理 Ctrl+C?我知道我可以从 v2 中的 cmdlet 执行此操作,方法是包含 Powershell.Stop()
方法的覆盖,但我找不到在脚本中使用的模拟。
我目前正在执行清理via an end
block,但是当脚本被取消时我需要执行额外的工作(而不是运行到完成)。
【问题讨论】:
Is there a way to catch ctrl-c and ask the user to confirm?的可能重复 【参考方案1】:您可以使用here on PoshCode中描述的方法
总结:
设置
[console]::TreatControlCAsInput = $true
然后使用
轮询用户输入if($Host.UI.RawUI.KeyAvailable -and (3 -eq
[int]$Host.UI.RawUI.ReadKey("AllowCtrlC,IncludeKeyUp,NoEcho").Character))
【讨论】:
哇,太疯狂了。我最终只是将我的脚本重写为 C# 中的 cmdlet,这样我就可以覆盖 Stop()。【参考方案2】:try-catch-finally 的 documentation 说:
即使您使用 CTRL+C 停止脚本,Finally 块也会运行。最后 如果 Exit 关键字从 Catch 中停止脚本,块也会运行 块。
请参阅以下示例。运行它并按ctrl-c
取消它。
try
while($true)
"Working.."
Start-Sleep -Seconds 1
finally
write-host "Ended work."
【讨论】:
这是真的,但最终会运行不仅因为 Exit 被调用,而且如果 Try 块成功。正如我在问题中指出的那样,当脚本被取消(而不是运行到完成)时,我需要执行额外的工作。 @fatcat111 使用布尔标志。例如,在try
的末尾设置$didcomplete = $true
并在finally
内使用if ($didcomplete) Write-Host "Ended work."
进行检查
很遗憾,如果关闭 PowerShell 控制台窗口,finally 块不会执行。
在停止远程 PSSession 调用命令或作业时也会调用 finally 块!【参考方案3】:
$PSCmdlet
上还有一个 Stopping
属性可用于此目的。
【讨论】:
Stopping
是 false
,即使在按 PowerShell/PowerShell#6322 停止时也是如此。【参考方案4】:
这是最近的工作解决方案。我在需要控制执行中断(关闭文件句柄)的循环中使用 if 部分。
[Console]::TreatControlCAsInput = $true # at beginning of script
if ([Console]::KeyAvailable)
$readkey = [Console]::ReadKey($true)
if ($readkey.Modifiers -eq "Control" -and $readkey.Key -eq "C")
# tasks before exit here...
return
另请注意,有一个错误导致 KeyAvailable 在脚本启动时为真。您可以通过在开始时读取调用 ReadKey 来缓解。这种方法不需要,只是在这种情况下值得了解。
【讨论】:
以上是关于在 Powershell 中优雅地停止的主要内容,如果未能解决你的问题,请参考以下文章