First off, either A) I'm not investigating into this hard enough or B) I've found a problem that requires some funky hack. By the way this is posh v1.0.
首先,要么A)我不是在考虑这个问题,或者B)我发现了一个需要一些时髦黑客的问题。顺便说一下,这是豪华版v1.0。
Here it goes:
它来了:
A week or so ago I asked a question about redirecting the output from the exection of an EXE in powershell that was otherwise not being caught. I was swiftly presented with "2>&1" which solved the problem.
大约一个星期前,我问了一个问题,关于在PowerShell中执行EXE的输出重定向,否则它将被捕获。我很快得到了“2>&1”,这解决了这个问题。
Now I've hit another snag and hope to see what some of you *ers can throw at it.
现在我又遇到了另一个障碍,并希望看到你们中的一些人可以扔掉它们。
I'm using try-catch blocks throughout my code as a good programmer should. When I went to place a call to GPG (gnupg.org), passing it a few commands as follows:
我在代码中使用try-catch块作为优秀的程序员应该。当我打电话给GPG(gnupg.org)时,传递一些命令,如下所示:
try `
{
& $gpgExeLocation --import $keyFileName 2>&1 | out-file "theOutput.txt";
} `
-Catch `
{
write-host "$_";
}
I get a blank text file (theOutput.txt).
我得到一个空白文本文件(theOutput.txt)。
But if I do the same call outside of the try-catch block, the text file gets some text written to it as expected.
但是如果我在try-catch块之外执行相同的调用,则文本文件会按预期写入一些文本。
What I'm wondering is if there is an issue with output redirection to stdout and the way powershell traps exceptions - or if it is my try-catch code to begin with?
我想知道是否存在输出重定向到stdout的问题以及powershell捕获异常的方式 - 或者如果它是我的try-catch代码开始?
here is my try-catch implementation
这是我的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 个解决方案
#1
It appears you are using a custom Try function with a -Catch parameter. Mind sharing your implementation to see if that could be causing the problem?
您似乎正在使用具有-Catch参数的自定义Try函数。介意分享您的实施,看看是否可能导致问题?
BTW I doubt that your catch statement would ever be invoked unless you are converting the non-terminating error condition of $lastexitode -ne 0 to a terminating error. In this case, you may be better off with a function like this. I use it a lot (it's quite handy):
顺便说一下,我怀疑你的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)"
}
}
Use it like so:
像这样使用它:
& $gpgExeLocation --import $keyFileName 2>&1 | out-file "theOutput.txt"
CheckLastExitCode
#1
It appears you are using a custom Try function with a -Catch parameter. Mind sharing your implementation to see if that could be causing the problem?
您似乎正在使用具有-Catch参数的自定义Try函数。介意分享您的实施,看看是否可能导致问题?
BTW I doubt that your catch statement would ever be invoked unless you are converting the non-terminating error condition of $lastexitode -ne 0 to a terminating error. In this case, you may be better off with a function like this. I use it a lot (it's quite handy):
顺便说一下,我怀疑你的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)"
}
}
Use it like so:
像这样使用它:
& $gpgExeLocation --import $keyFileName 2>&1 | out-file "theOutput.txt"
CheckLastExitCode