使用IDE时从Powershell调用第三方可执行文件时出错

Luc*_*cas 64 ide powershell du powergui

我有一个PowerShell脚本,它使用du.exe(最初来自Sysinternals的磁盘使用情况)来计算目录的大小.

如果我du c:\Backup在控制台中运行,它按预期工作,但在ISE或PowerGui中运行的相同代码行给出了预期的结果加上错误

+ du <<<<  c:\backup
+ CategoryInfo          : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Run Code Online (Sandbox Code Playgroud)

这是为什么?如何避免此错误?我尝试使用invoke-expression &,但是没有去.

谢谢您的帮助.

Kei*_*ill 46

为避免这种情况,您可以将stderr重定向为null,例如:

du 2> $null
Run Code Online (Sandbox Code Playgroud)

本质上,控制台主机和ISE(以及远程处理)以不同方式处理stderr流.在控制台主机上,PowerShell支持像edit.com这样的应用程序与其他将彩色输出和错误写入屏幕的应用程序一起工作非常重要.如果未在控制台主机上重定向I/O流,则PowerShell会为本机EXE提供直接写入的控制台句柄.这绕过的PowerShell这样的PowerShell不能看到有这么写也不能报告通过$错误或写信给PowerShell的标准错误流的错误错误.

ISE和远程处理不需要支持这种情况,所以他们确实看到stderr上的错误,然后写错误并更新$ error.

  • 在一般情况下,隐藏 stderr 是一个坏主意,最好将其重定向到 stdout。 (4认同)
  • 这个答案丢弃了标准错误,**因此从根本上来说是疯狂的。** 请参阅 [sschuberth](/sf/users/78923981/) 的答案 [one-liner redirecting stderr to stdout * and * reserved标准选项传递语法](/sf/answers/1466529501/) – 与[下一个答案](/sf/answers/1143393261/)不同,它在传递时在语法上会崩溃选项。 (4认同)

Sim*_*ing 39

我最近一直面临同样的问题,但我想将stderr输出定向到stdout.您会认为以下内容可行:

    & du 2>&1
Run Code Online (Sandbox Code Playgroud)

但PowerShell将解释重定向并在'du'完成后处理它.我找到的解决方法是使用cmd.exe/c调用它:

    & cmd /c 'du 2>&1'
Run Code Online (Sandbox Code Playgroud)

  • 这对我有用.我还需要传递选项,所以我的完整语法是``&cmd/c'foo.exe 2>&1'option1 option2```.(请注意,只有可执行文件名称和"2>&1"在单引号内.) (6认同)

ssc*_*rth 23

另一种抑制NativeCommandError输出的方法是将管道中的对象转换为字符串,如本答案底部所述:

du c:\Backup 2>&1 | %{ "$_" }
Run Code Online (Sandbox Code Playgroud)

  • **我讨厌您,PowerShell。**尽管这种厌恶情绪很深,但我还是为上面的一句话所含的疯狂所称赞。是的,它不可读。但是不是吗?这是*最终的解决方案。而[接受的答案](/sf/answers/146693641/)丢弃所有stderr(*明显有害!*)和[下一个答案](/sf/answers/1143393261/ 2809027)遵循`CMD.exe`(*传递选项时,可读性比该解决方案还低!),此答案将stderr重定向到stdout *,并且*保留了标准选项传递语法。 (8认同)
  • 其次你的观点@Cecil Curry。请注意,虽然我喜欢这个答案,因为它很干净,但不幸的是它不适用于 $ErrorActionPreference="Stop"。所以我不得不求助于 cmd /c 包装。叹。 (2认同)