【问题标题】:Gracefully stopping in Powershell在 Powershell 中优雅地停止
【发布时间】:2010-12-15 04:56:08
【问题描述】:

如何在 PowerShell 脚本中捕获和处理 Ctrl+C?我知道我可以从 v2 中的 cmdlet 执行此操作,方法是包含 Powershell.Stop() 方法的覆盖,但我找不到在脚本中使用的模拟。

我目前正在执行清理via an end block,但是当脚本被取消时我需要执行额外的工作(而不是运行到完成)。

【问题讨论】:

标签: powershell powershell-2.0


【解决方案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 属性可用于此目的。

【讨论】:

【解决方案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 来缓解。这种方法不需要,只是在这种情况下值得了解。

【讨论】:

    猜你喜欢
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 2018-09-27
    • 2019-11-10
    • 1970-01-01
    • 2018-09-08
    • 2021-06-04
    • 1970-01-01
    相关资源
    最近更新 更多