使用IDE时从Powershell调用第三方可执行文件时出错
我有一个PowerShell脚本,它使用du.exe(最初来自Sysinternals的磁盘使用 )来计算目录的大小。
如果我在控制台中运行du c:\Backup
,它可以按预期工作,但是在ISE或PowerGui中运行的同一行代码会给出预期的结果和错误
+ du <<<< c:\backup + CategoryInfo : NotSpecified: (:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError
这是为什么? 我如何避免这个错误? 我试着调用expression式,使用&
,但没有去。
谢谢您的帮助。
为了避免这种情况,你可以将stderrredirect到null,例如:
du 2> $null
本质上,控制台主机和ISE(以及远程处理)不同地处理stderrstream。 在控制台主机上,PowerShell支持像edit.com这样的应用程序与其他将颜色输出和错误写入屏幕的应用程序一起工作非常重要。 如果I / Ostream未在控制台主机上redirect,则PowerShell会为本机EXE提供控制台句柄以直接写入。 这绕过了PowerShell,所以PowerShell无法看到写入错误,因此无法通过$ error或通过写入PowerShell的stderrstream来报告错误。
ISE和远程处理不需要支持这种情况,所以他们确实看到stderr上的错误,随后写入错误并更新$错误。
我最近一直面临着同样的问题,但我想要将stderr输出指向stdout。 你会认为下面的工作:
& du 2>&1
但是,'du'完成后,PowerShell将解释redirect并处理它。 我find的解决方法是使用cmd.exe / c调用它:
& cmd /c 'du 2>&1'
抑制NativeCommandError
输出的另一种方法是将pipe道中的对象转换为string ,如本答案底部所示 :
du c:\Backup 2>&1 | %{ "$_" }
尝试:
du 2>&1 | %{ "$_" }
之前的FIX会redirect错误,但如果您的用户名或密码不好,或者如果使用集成身份validation,则无法访问,您可能会丢失真正的错误。
所以这里是一个实现error handling的方法,并绕过由psexec引发的特定错误(这不是一个错误)。
try{ psexec command ..... } catch [System.Management.Automation.RemoteException]{ if ($_.TargetObject -like "Connecting to *" -and $_.CategoryInfo.Category -eq "NotSpecified" -and $_.FullyQualifiedErrorId -eq "NativeCommandError" -and $_.InvocationInfo.MyCommand.Name -like "psexec*.exe"){ $error.Remove[$Error[0]] } else{ Throw } } catch{ throw }