【问题标题】:Ouput redirection/capturing issue with Powershell and Try-Catch and external EXEPowershell 和 Try-Catch 以及外部 EXE 的输出重定向/捕获问题
【发布时间】:2013-09-18 01:17:03
【问题描述】:

首先,要么 A) 我对此的调查不够努力,要么 B) 我发现了一个需要一些时髦的 hack 的问题。顺便说一句,这是豪华 v1.0。

这里是:

大约一周前,我问了一个关于重定向在 powershell 中执行 EXE 的输出的问题,否则不会被捕获。我很快就收到了解决问题的“2>&1”。

现在我遇到了另一个障碍,希望看看你们中的一些 stackoverflowers 能解决什么问题。

我在我的代码中使用了 try-catch 块,就像一个优秀的程序员应该做的那样。当我去调用 GPG (gnupg.org) 时,向它传递了一些命令,如下所示:

try `
{
    & $gpgExeLocation --import $keyFileName 2>&1 | out-file "theOutput.txt";
} `
-Catch `
{
    write-host "$_";
}

我得到一个空白文本文件 (theOutput.txt)。

但是,如果我在 try-catch 块的 outside 执行相同的调用,文本文件会按预期将一些文本写入其中。

我想知道的是,输出重定向到 stdout 是否存在问题以及 powershell 捕获异常的方式 - 还是我的 try-catch 代码开始?

这是我的 try-catch 实现

function global:try
{
    param
    (
        [ScriptBlock]$Command = $(Throw "The parameter -Command is required."),
        [ScriptBlock]$Catch   = { Throw $_ },
        [ScriptBlock]$Finally = {}
    )

    & {
        $local:ErrorActionPreference = "SilentlyContinue"

        trap
        {
            trap
            {
                & {
                    trap { Throw $_ }
                    &$Finally
                }

                Throw $_
            }

            $_ | & { &$Catch }
        }

        &$Command
    }

    & {
        trap { Throw $_ }
        &$Finally
    }
};

【问题讨论】:

    标签: powershell powershell-1.0


    【解决方案1】:

    您似乎正在使用带有 -Catch 参数的自定义 Try 函数。介意分享你的实现,看看这是否会导致问题?

    顺便说一句,我怀疑您的 catch 语句是否会被调用,除非您将 $lastexitode -ne 0 的非终止错误条件转换为终止错误。在这种情况下,使用这样的功能可能会更好。我经常使用它(它很方便):

    function Get-CallStack {
        trap { continue }
        1..100 | foreach {
            $var = Get-Variable -scope $_ MyInvocation
            $var.Value.PositionMessage -replace "`n"
        }
    }
    
    #--------------------------------------------------------------------
    # Helper function to deal with legacy exe exit codes
    #--------------------------------------------------------------------
    function CheckLastExitCode {
        param ([int[]]$SuccessCodes = @(0), [scriptblock]$CleanupScript=$null)
    
        if ($SuccessCodes -notcontains $LastExitCode) {
            if ($CleanupScript) {
                "Executing cleanup script: $CleanupScript"
                &$CleanupScript
            }
            $OFS = $NL = [System.Environment]::NewLine
            throw "EXE RETURNED EXIT CODE ${LastExitCode}${NL}$(Get-CallStack)"
        }
    }
    

    像这样使用它:

    & $gpgExeLocation --import $keyFileName 2>&1 | out-file "theOutput.txt"
    CheckLastExitCode
    

    【讨论】:

    • 我很高兴并且没有阅读您的代码。我要试一试,看看会发生什么。我很感激。
    • 成功!用一些错误的参数调用 gpg 并轻松捕获返回码。我很感激你花时间提供帮助。干杯!
    • 对 powershell 2.0 仍然有效?
    猜你喜欢
    • 2010-10-29
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 2014-07-26
    • 2011-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多