2009-06-08 4 views
2

Прежде всего, A) Я не расследую это достаточно сложно или B) Я нашел проблему, требующую некоторого фанкового взлома. Кстати, это posh v1.0.Проблема с перенаправлением/захватом Ouput с Powershell и Try-Catch и внешним EXE

Вот он идет:

Через неделю или около того назад я задал вопрос о перенаправлении вывода из exection в качестве 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, текстовый файл получает текст, написанный для него, как и ожидалось.

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

ответ

2

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

BTW Я сомневаюсь, что ваш оператор 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 
+0

меня вызвать счастливым и читать ваш техника его подводит код. Я собираюсь попробовать и посмотреть, что произойдет. Я ценю это. – CLR

+0

Успех! Вызывается gpg с некоторыми плохими аргументами, и он легко поймал код возврата. Я ценю время, которое вы приняли, чтобы помочь. Ура! – CLR

+0

по-прежнему действует для powershell 2.0? – Kiquenet