如果PowerShell脚本终止,则执行代码

时间:2016-02-15 16:40:54

标签: powershell nunit powershell-ise

如果强行终止PowerShell脚本,是否可以强制执行某些代码?我尝试过try..finally和Traps,但它们似乎都不起作用,至少当我从PowerShell ISE按Ctrl-C时。

基本上,我有一个执行PowerShell脚本的Jenkins构建。如果出于任何原因我想要从Jenkins中停止构建,我不希望任何子进程锁定文件,从而使我的构建项目处于破坏状态,直到管理员手动终止违规进程({{1}在我的情况下)。因此,如果发生这种情况,我希望能够强制执行终止nunit-agent.exe的代码。

更新:正如下面提到的@Frode,我尝试使用nunit-agent.exe

try..finally

然后当我执行此操作并使用Ctrl-C打破进程时,我没有输出。我认为我应该得到的是:

$sleep = {
  try {
    Write-Output "In the try block of the job."
    Start-Sleep -Seconds 10
  }
  finally {
    Write-Output "In the finally block of the job."
  }
}

try {
  $sleepJob = Start-Job -ScriptBlock $sleep
  Start-Sleep -Seconds 5
}
finally {
  Write-Output "In the finaly block of the script."
  Stop-Job $sleepJob
  Write-Output "Receiving the output from the job:"
  $content = Receive-Job $sleepJob
  Write-Output $content
}

1 个答案:

答案 0 :(得分:2)

我使用try {} finally {}。当try尝试完成或者你使用ctrl + c时,finally块会运行,所以你需要运行任何一种运行安全的命令,例如。如果你杀了一个已经死的进程并不重要......

或者您可以使用$?添加测试以查看最后一个命令是否成功,例如:

try {
    Write-Host "Working"
    Start-Sleep -Seconds 100

} finally {
    if(-not $?) { Write-Host "Cleanup on aisle 5" }
    Write-Host "Done"
}

或者创建自己的测试(以防万一由于某种原因,尝试中的最后一个命令失败):

try {
    $IsDone = $false
    Write-Host "Working"
    Start-Sleep -Seconds 100
    #.....
    $IsDone = $true

} finally {
    if(-not $IsDone) { Write-Host "Cleanup on aisle 5" }
    Write-Host "Done"
}

UPDATE :finally块不适用于输出,因为管道在CTRL + C上停止。

  

请注意,按CTRL + C会停止管道。发送给的对象   管道不会显示为输出。因此,如果你   包括要显示的语句,例如“Finally block has run”,   按CTRL + C后不会显示,即使是最后一个   阻止了。

来源:about_Try_Catch_Finally

但是,如果将Receive-Job的输出保存到全局变量$global:content = Receive-Job $sleepJob,则可以在finally块之后读取它。该变量通常在不同的局部范围内创建,并在finally块之后丢失。