处理键盘中断,执行结束块

时间:2013-12-20 17:13:32

标签: powershell

我有一个处理文件列表的powershell函数。我为此使用了beginprocessend块:

begin {
    # prepate some stuff
}
process {
    # process each file
}
end {
    # clean up
}

现在,当我点击 Ctrl + C 时,整个脚本就会在它所在的位置终止。这对于流程部分来说并不是一个问题,因为它只会对最后一个命令进行永久性更改。

但是我仍然希望执行end块中的内容来清理它,并打印一些有关管理得到处理的文件的统计信息。

是否有一种干净的方法来捕获键盘中断,同时保持开始/进程/结束结构?

2 个答案:

答案 0 :(得分:3)

执行此操作的一种方法是在脚本块运行时禁用 Ctrl-C 作为中断的处理。你必须手动检查它是否突然失控,但它应该保证结束块运行

begin { 
  [Console]::TreatControlCAsInput = $true
}
process {
  # Maybe check for Ctrl-C here to terminate processing
}
end { 
  [Console]::TreatControlCAsInput = $false
}

为了以非阻塞的方式检查 Ctr-C 作为输入,您可以执行以下操作

if ([Console]::KeyAvailable) {
  $key = [Console]::ReadKey($true)
  if ($key.key -eq "C" -and $key.modifiers -eq "Control") { 
    # Clean up and exit
  }
}

答案 1 :(得分:-1)

当脚本由于以下任何条件而终止时,try / catch / finally块集的“finally”部分仍然执行:

  • 按下Ctrl + C(随时)
  • 在catch部分
  • 中遇到Exit关键字
  • 发生了致命错误(在“最终”部分本身之外)

把你所有的清理工作都放在那里。无论发生了什么,它都会运行(编辑:除非“finally”块本身抛出错误)。

(进一步编辑:我将原始标记留在那里进行空间参考 - 它们现在已被删除,因此文字复制/粘贴不应包含无效关键字。

try { # begin, and/or process
}
catch { # optionally handle errors
}
finally { # clean up 
}

您可以将准备步骤和实际处理全部放在一个“try”块中,或者您可以创建其中两个块 - 无论哪种方式,“try”和“catch”都是必需的,“finally”是可选的。