Ошибка перенаправления / захвата Ouput с Powershell и Try-Catch и внешним EXE - PullRequest
2 голосов
/ 08 июня 2009

Во-первых, либо А) Я не занимаюсь этим достаточно сложно, либо Б) Я обнаружил проблему, которая требует некоторого хакерского взлома. Кстати это шикарный v1.0.

Вот так:

Примерно неделю назад я задал вопрос о перенаправлении вывода из exe-файла exe в powershell, который иначе не был перехвачен. Мне быстро представили «2> & 1», что решило проблему.

Теперь я столкнулся с еще одной загадкой и надеюсь увидеть, что некоторые из вас могут использовать для создания стековых потоков.

Я использую блоки try-catch по всему коду, как должен делать хороший программист. Когда я пошел позвонить в GPG (gnupg.org), передал ему несколько команд следующим образом:

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

Я получаю пустой текстовый файл (theOutput.txt).

Но если я сделаю тот же вызов за пределами блока try-catch, текстовый файл получит некоторый текст, записанный в него, как и ожидалось.

Что мне интересно, так это то, что существует проблема с перенаправлением вывода на стандартный вывод и способом перехвата исключений 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
    }
};

1 Ответ

2 голосов
/ 08 июня 2009

Похоже, вы используете пользовательскую функцию Try с параметром -Catch. Не могли бы вы поделиться своей реализацией, чтобы узнать, может ли это быть причиной проблемы?

Кстати, я сомневаюсь, что ваш оператор 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
...