【问题标题】:Powershell Errors out correctly in ISE but doesnt in Command line executionPowershell 错误在 ISE 中正确输出,但在命令行执行中没有
【发布时间】:2012-07-09 06:57:00
【问题描述】:

我在 powershell ISE 中运行的命令退出了我的预期,但是当我将代码移动到命令行以在不同的环境中执行时,我不再收到错误消息。该错误仅发生在 ISE 中。我曾尝试像其他人发布的那样在命令行上使用 -sta,但没有运气。

$SIEBEL_HOME\srvrmgr.exe /c "Run Command"
echo "Exit Code: $lastExitCode - Return Code: $?"

当我通过 ISE 运行它时,我得到以下输出:

Exit Code: 0 - Return Code: False

当我在命令行上运行该命令时,我得到以下输出:

E:\powershell.exe -sta -file script.ps1

Exit Code: 0 - Return Code: True

如您所见,我正在尝试检查返回码并在 ISE 中获得正确的操作,但没有通过命令行获得正确的结果。

我想知道 Windows 在 ISE 中运行时是否使用了不同的环境变量。我注意到,当我通过 ISE 运行它时,控制台会以红色显示错误。

【问题讨论】:

  • 您的脚本应该是可执行的。如果您直接调用它,而不是将其作为参数传递给 powershell,会发生什么?
  • 我得到相同的结果直接调用它作为一个可执行文件。

标签: powershell powershell-2.0 powershell-ise


【解决方案1】:

$? 变量仅检查最后执行的 PowerShell 命令的成功状态,而不检查外部可执行文件。

$LASTEXITCODE 变量检测外部可执行文件的最后退出代码。

如您所见,这些变量用于不同的目的,因此您不会看到它们之间的一致性。有关它们的更多信息,请运行以下命令:

 Get-Help -Name about_Automatic_Variables

编辑:运行此代码以显示 $?变量有效。

# Here we'll show a successful command, and then a failed .NET method call
Write-Output -Object "hi"; # Run a successful command
Write-Host -Object $?; # True = command succeeded
[System.IO.File]::NonExistentMethod();
Write-Host -Object $?; # False = command failed

# Here we'll show a successful command, followed by a failed executable call
Write-Output -Object "hi" | Out-Null; # Run a successful command
Write-Host -Object $?; # True = last command ran successfully
ipconfig /nonexistentparameter | Out-Null;
Write-Host -Object $?; # False = last command did not run successfully

对我来说,运行 PowerShell v3 Release Candidate,它在控制台中的工作方式与 ISE 相同。

【讨论】:

  • 我同意 LastExitCode 和 $? 之间的它们不应该相同。最后一个命令的成功状态是我正在寻找的,它通过 ISE 给出正确的响应。当我通过命令行 powershell 执行相同的脚本并给出相同的错误时,我希望得到相同的结果......但我收到的响应不一致。我不明白为什么$? ISE 和命令行之间的处理方式不同。我一直在寻找为什么这些不同的解释,以便我可以决定如何处理错误检查,但我似乎找不到。
  • 感谢您的示例。我也从你的两个例子中得到正确的输出。这是一个奇怪的场景,因为即使出现错误,可执行文件也总是返回退出代码 0,这就是我们无法编写 bat 脚本的原因。然后,当我在 ISE 中编写 power shell 时,我注意到它能够检测到错误(不知何故)。只是希望我知道为什么命令行无法检测到它会迫使我通过解析日志来编写自定义错误处理代码。
【解决方案2】:

我对您的情况有另一种解决方案。如果您想编写一些代码来确定外部可执行文件的退出代码,您可以使用 Start-Process cmdlet 来发挥您的优势。事实上,我通常建议人们使用Start-Process cmdlet 而不是直接调用外部可执行文件,因为它有助于更​​好地处理参数值。就您而言,另一个好处是您可以将-PassThru-WaitStart-Process 一起使用,这意味着您可以获得一个表示该进程的对象,该对象还将包括其退出代码。

$CliArgs = '/all';
$Process = Start-Process -FilePath ipconfig.exe -ArgumentList $CliArgs -NoNewWindow;
Write-Host -Object $Process.ExitCode;

【讨论】:

    【解决方案3】:

    PowerShell ISE 处理错误的方式与 PowerShell 控制台不同。在 ISE 中,从控制台应用程序到其 stderr 流的所有输出都被写入 PowerShell 的错误流。我还没有找到改变这种行为的方法。

    【讨论】:

    • 实际上这个答案可能最接近解决您的问题。如果将错误流重定向到输出流,命令行中会发生什么:$SIEBEL_HOME\srvrmgr.exe /c "Run Command" 2>&1.我怀疑$_会返回false,因为PS在管道中遇到了错误记录。
    猜你喜欢
    • 1970-01-01
    • 2021-10-23
    • 2015-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-27
    • 1970-01-01
    • 2014-10-27
    相关资源
    最近更新 更多