告诉PowerShell ISE不要发送stderr以写入错误

告诉PowerShell ISE不要发送stderr以写入错误,powershell,powershell-ise,Powershell,Powershell Ise,当可执行文件写入标准错误流(stderr)时,PowerShell控制台和PowerShell ISE的行为不同。控制台(powershell.exe)将其显示为标准输出。例如,当我在非存储库中获得Mercurial的状态时,它会写入标准错误: > hg st -R C:\Windows abort: repository C:\Windows not found! 但是,在PowerShell ISE(PowerShell_-ISE.exe)中,该错误会传递给PowerShell的写入

当可执行文件写入标准错误流(
stderr
)时,PowerShell控制台和PowerShell ISE的行为不同。控制台(powershell.exe)将其显示为标准输出。例如,当我在非存储库中获得Mercurial的状态时,它会写入标准错误:

> hg st -R C:\Windows
abort: repository C:\Windows not found!
但是,在PowerShell ISE(
PowerShell_-ISE.exe
)中,该错误会传递给PowerShell的
写入错误
cmdlet:

> hg st -R C:\Windows
hg.exe : abort: repository C:\Windows not found!
At line:1 char:3
+ hg <<<<  st -R C:\Windows
    + CategoryInfo          : NotSpecified: (abort: repository C:\Windows not found!:String) [], RemoteExcepti 
   on
    + FullyQualifiedErrorId : NativeCommandError
hg st-R C:\Windows hg.exe:abort:repository C:\Windows未找到! 第1行字符数:3
+hg将stderr输出重定向到stdout“应该”起作用,但在ISE中不起作用。在这种情况下,最好的办法是使错误输出静音,如下所示:

& {
    $ErrorActionPreference = 'SilentlyContinue'
    hg st -R C:\Windows 2>&1
}
通过在嵌套范围中执行设置此变量,可以避免全局设置它。退出上述作用域时,
$ErrorActionPreference
的全局版本仍然设置为以前的版本

不幸的是,ISE和控制台的行为有所不同,但我的理解是,对于“控制台”,另一个控制台应用程序只是获得控制台句柄,因此它直接输出到控制台(绕过PowerShell)。ISE不是基于控制台的,所以它试图使本机stderr能够很好地处理PowerShell错误流。在这种情况下,控制台的行为并不理想。所以,让ISE与控制台保持一致更好,还是让ISE更好地处理stderr更好(除了不尊重流重定向的部分)?显然,PowerShell与后者一起使用

hg st -R C:\Windows 2>&1 | %{ if ($_ -is [System.Management.Automation.ErrorRecord]) { $_.Exception.Message } else { $_ } }

这将保留stderr输出并将其作为正常输出发送,而不是丢弃它。

这不起作用。它仍然使用
Write error
@splattedbits写入错误是的,它仍然这样做。我更新了我的答案,提供了另一个选择。谢谢!经过半天的实验,这种方法显然是赢家。它有它的缺点,但总的来说,它可以满足我的需要。我目前在Win7上看到的Powershell 4是:Powershell控制台和ISE的行为确实与所描述的方式相同,但是当从控制台运行Powershell脚本
.ps1
时,或者当从正常的cmd窗口调用
Powershell脚本.ps1
时,然后,stderr流的行为将类似于ISE,即使用Write Error。