Ошибка при вызове стороннего исполняемого файла из Powershell при использовании IDE - PullRequest
59 голосов
/ 19 января 2010

У меня есть сценарий PowerShell, который использует du.exe ( Использование диска первоначально от Sysinternals) для расчета размера каталогов.

Если я запускаю du c:\Backup в консоли, она работает как положено, но та же строка кода, выполняемая в ISE или PowerGui, дает ожидаемый результат плюс ошибка

+ du <<<<  c:\backup
+ CategoryInfo          : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

Почему это? Как мне избежать этой ошибки? Я попытался вызвать выражение, используя &, но не пошло.

Спасибо за помощь.

Ответы [ 5 ]

44 голосов
/ 19 января 2010

Чтобы избежать этого, вы можете перенаправить stderr на ноль, например ::100100

du 2> $null

По существу, консольный хост и ISE (а также удаленное взаимодействие) по-разному обрабатывают поток stderr. На хосте консоли было важно, чтобы PowerShell поддерживал такие приложения, как edit.com, для совместной работы с другими приложениями, которые записывают цветной вывод и ошибки на экран. Если поток ввода-вывода не перенаправляется на хост консоли, PowerShell предоставляет собственному EXE-файлу дескриптор консоли для прямой записи. Это обходит PowerShell, поэтому PowerShell не может видеть, что записаны ошибки, и поэтому не может сообщить об ошибке через $ error или путем записи в поток stderr PowerShell.

ISE и удаленное взаимодействие не должны поддерживать этот сценарий, поэтому они видят ошибки на stderr и впоследствии записывают ошибку и обновляют $ error.

35 голосов
/ 02 мая 2013

Недавно я столкнулся с такими же проблемами, но я хотел бы, чтобы вывод stderr был направлен на stdout. Можно подумать, что будет работать следующее:

    & du 2>&1

Но PowerShell интерпретирует перенаправление и обрабатывает его после завершения 'du'. Обходной путь, который я нашел, - это вызвать его с помощью cmd.exe / c:

    & cmd /c 'du 2>&1'
17 голосов
/ 06 января 2014

Другой способ подавить вывод NativeCommandError состоит в преобразовании объектов в конвейере в строки , как указано в нижней части этого ответа :

du c:\Backup 2>&1 | %{ "$_" }
3 голосов
/ 20 октября 2016

Попробуйте:

du 2>&1 | %{ "$_" }
1 голос
/ 17 февраля 2017

Предыдущая FIX будет перенаправлять ошибки, но вы можете потерять настоящую ошибку, если, например, ваше имя пользователя или пароль не годятся или если вы используете встроенную аутентификацию, у вас нет доступа.

Итак, вот способ реализовать обработку ошибок и обойти конкретную ошибку (которая не является одной), вызванную 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
            }
...