如何在Powershell中不断尝试某些东西,直到成功为止?

时间:2018-09-19 10:22:13

标签: windows powershell scripting powershell-v3.0 powershell-v4.0

使用基本结构:

try
{
    Do-Something
}
catch
{
    Write-Output "Something threw an exception"
}

是否可以继续尝试做某事直到成功?也许使用while loopp像这样:

$Timeout = 60
$timer = [Diagnostics.Stopwatch]::StartNew()
$t = 0
while (($timer.Elapsed.TotalSeconds -lt $Timeout) -and ($t -ne 1))) {
    Start-Sleep -Seconds 1
    try
    {
        Do-Something
        $t = 1
    }
    catch
    {
        Write-Output "Something threw an exception"
    }
}
$timer.Stop()

在这里,我使用计时器来确保PowerShell不会无限期运行。 它应继续尝试,直到try成功并执行$t = 1为止。但是,它在大约2秒钟内失败。请帮忙。

更具体地讲,Do-Something是:

(Get-Process -Name FineReader).MainWindowHandle

我希望代码继续尝试直到FineReader存在并且它可以获取MainWindowHandle

3 个答案:

答案 0 :(得分:1)

您可以使用ng g @briebug/jest-schematic:add关键字。

break

答案 1 :(得分:0)

您的Do-Something应该用开关-ErrorAction Stop调用,以便发出可以被try捕获的终止异常

为此,您还需要将函数绑定为CmdLet。例如:

function DoSomething {
    [CmdLetBinding()]
    Param(
    )

    # Your code

}

然后使用-ErrorAction Stop开关调用函数:

try {
    Do-Something -ErrorAction Stop
}

如果您的DoSomething不是函数而是现有的Powershell CmdLet,则...您猜对了,只需用-ErrorAction Stop进行调用

您可以在powershell here

中进一步了解try / catch / finally。

答案 2 :(得分:0)

假设您有一个函数在10个调用中有9个失败:

function Get-RandomFail{
    $value = [Random]::new().Next(10);
    if ($value -ne 5) { throw }
    return $value
}

要限制时间窗口,可以使用以下命令:

function Try-Invoke{
    [CmdletBinding()]
    param(
        $Action,
        $MaxSeconds,
        $Delay=1
    )
    $timeout = [timespan]::FromSeconds($MaxSeconds)
    $start = [DateTime]::Now
    do {
        try {
            return &$Action
        } catch {
            Write-Verbose "Error"
        }
        Start-Sleep -Seconds $Delay
    } until (([DateTime]::Now - $start) -gt $timeout)
    throw
}

$result = Try-Invoke {Get-RandomFail} -MaxSeconds 5 -Verbose

Get-RandomFail将被调用,直到没有错误发生或时间结束为止。您还可以使用Delay参数在每次不成功的Get-RandomFail调用之后修改睡眠时间。