PowerShell启动进程,带超时等待,终止并获取退出代码

22

我想在循环中重复执行一个程序。

有时候,这个程序会崩溃,因此我想杀掉它,以便下一次迭代可以正确启动。我通过超时来确定这一点。

我已经设置了超时,但无法获取程序的退出代码,这也是我需要确定其结果的原因。

以前,我没有使用超时等待,而是在Start-Process中使用了-wait,但如果启动的程序崩溃,脚本就会挂起。虽然在这种设置下,我可以正确地获取退出代码。

我是从ISE执行的。

for ($i=0; $i -le $max_iterations; $i++)
{
    $proc = Start-Process -filePath $programtorun -ArgumentList $argumentlist -workingdirectory $programtorunpath -PassThru
    # wait up to x seconds for normal termination
    Wait-Process -Timeout 300 -Name $programname
    # if not exited, kill process
    if(!$proc.hasExited) {
        echo "kill the process"
        #$proc.Kill() <- not working if proc is crashed
        Start-Process -filePath "taskkill.exe" -Wait -ArgumentList '/F', '/IM', $fullprogramname
    }
    # this is where I want to use exit code but it comes in empty
    if ($proc.ExitCode -ne 0) {
       # update internal error counters based on result
    }
}

我该如何

  1. 启动进程
  2. 等待进程有序执行并完成
  3. 在进程崩溃(如超时)时杀死它
  4. 获取进程的退出代码

如何在PowerShell中等待并终止超时进程 - phuclv
1个回答

32

您可以更简单地使用$proc | kill$proc.Kill()终止进程。请注意,在这种情况下,您将无法检索退出代码,您应该只更新内部错误计数器:

for ($i=0; $i -le $max_iterations; $i++)
{
    $proc = Start-Process -filePath $programtorun -ArgumentList $argumentlist -workingdirectory $programtorunpath -PassThru

    # keep track of timeout event
    $timeouted = $null # reset any previously set timeout

    # wait up to x seconds for normal termination
    $proc | Wait-Process -Timeout 4 -ErrorAction SilentlyContinue -ErrorVariable timeouted

    if ($timeouted)
    {
        # terminate the process
        $proc | kill

        # update internal error counter
    }
    elseif ($proc.ExitCode -ne 0)
    {
        # update internal error counter
    }
}

谢谢!在你的解决方案中,Wait-Process 正确等待了 400 秒,但是“# terminate the process”子句在超时后从未触发,因此进程也从未被终止,在下一次迭代之后,将有 2 个进程正在运行。(我使用了一个小的超时时间来强制出现这种情况进行测试。) - Andreas Reiff
2
你是对的,我以为 Wait-Process 会返回一些东西。我编辑了我的答案,现在将错误消息分配给 $timeouted,在发生超时的情况下,它被设置。 - Martin Brandl
谢谢!(有一个小错别字。)工作得很好! - Andreas Reiff
1
抱歉,不应该使用别名。ea 表示 ErrorAction,0 是 SilentlyContinue 枚举值 - 因此我将此行的 ErrorAction 设置为 SilentlyContinue(这可以防止脚本在出现错误时停止)。-ev 代表 ErrorVariable。我基本上定义了如果发生错误,则将其写入 $timeout 变量。 - Martin Brandl
2
@AlekDavis 不,你在那里省略了 $ 符号。 - Martin Brandl
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接