PowerShell - переключатели Start-Process и Cmdline

79

Я могу запустить это нормально:

$msbuild = "C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe" 
start-process $msbuild -wait

Но когда я запускаю этот код (ниже), я получаю сообщение об ошибке:

$msbuild = "C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /v:q /nologo" 
start-process $msbuild -wait

Есть ли способ передать параметры в MSBuild с помощью start-process? Я открыт для того, чтобы не использовать start-process, единственная причина, по которой я его использовал, заключалась в том, что мне нужно было иметь "команду" в качестве переменной.

Когда у меня есть
C: \ WINDOWS \ Microsoft.NET \ Framework \ v3.5 \ MSBuild.exe / v: q / nologo
в отдельной строке, как это обрабатывается в Powershell?

Должен ли я вместо этого использовать какую-то функцию eval ()?

BuddyJoe
источник
См. Blogs.msdn.com/powershell/archive/2007/01/16/… для получения информации об альтернативах start-process.
i_am_jorf
Спасибо jeffamaphone, это тоже была хорошая справочная информация.
BuddyJoe,
1
Имейте в виду, что Start-Process - это новая функция в V2. Информация в этом посте очень хороша, но некоторые из них больше не нужны в V2.
EBGreen
Сам Start-Process новичок в V2? Не могли бы вы немного уточнить? У меня нет машины с установленной версией V1 для тестирования.
BuddyJoe,
1
Я просто имею в виду, что командлета Start-Process не существовало в V1. В V1 вам нужно было использовать один из методов, перечисленных в сообщении блога, на которое ссылается Джеф.
EBGreen

Ответы:

124

вы захотите разделить свои аргументы в отдельный параметр

$msbuild = "C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe"
$arguments = "/v:q /nologo"
start-process $msbuild $arguments 
Glennular
источник
15
$argsпоскольку имя переменной не работает, оно зарезервировано. $argumentsВместо этого используйте или что-нибудь еще
joshcomley
1
Похоже, очередь предложений заполнена, но я бы посоветовал читателям понять, что -ArgumentListищет строку, поэтому пример другого ответа со строками, разделенными запятыми (технически массив), может работать из-за того, как PowerShell потенциально разворачивает его, но если вы желая передать список аргументов из массива, вероятно, лучше заранее «распаковать» его в строку.
dragon788
3
@ dragon788, get-help start-processуказывает, что -ArgumentList ожидаетString[]
asynchronos
60

Используя явные параметры, это будет:

$msbuild = 'C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe'
start-Process -FilePath $msbuild -ArgumentList '/v:q','/nologo'

РЕДАКТИРОВАТЬ: цитаты.

EBGreen
источник
Я думаю, что без них все было бы хорошо, но с ними определенно было бы хорошо, так что я отредактирую это
EBGreen
4
Кажется, более надежным в использовании-ArgumentList ('/v:q','/nologo')
Питер Тейлор
1
Powershell НАСТОЛЬКО многословен. git gui &- как это просто (* nix конечно)! По сравнению с start-Process git -ArgumentList gui. Знаю, знаю, бесполезно. В последнее время я немного поигрался с Powershell и сделал много приятных вещей; но многословие убийца!
HankCa
1
Что ж, это только то, что многословно, если вы хотите, чтобы это было: start git -args gui тоже работает. Я понимаю, что это все же более подробный, чем * nix. Дело в том, что если вы используете завершение табуляции и псевдонимы, то количество фактических нажатий клавиш значительно уменьшается. Я также добавлю, что многословие означает, что человек, который вообще не знает PowerShell, может прочитать команду PS и легче понять, что именно она делает. Просто разница в философии.
EBGreen 07
@HankCa,sajb { git gui }
asynchronos
7

Предупреждение

Если вы запускаете PowerShell из окна cmd.exe, созданного Powershell, второй экземпляр больше не ждет завершения задания.

cmd>  PowerShell
PS> Start-Process cmd.exe -Wait 

Теперь из нового окна cmd снова запустите PowerShell и в нем запустите второе окно cmd: cmd2> PowerShell

PS> Start-Process cmd.exe -Wait
PS>   

Второй экземпляр PowerShell больше не соблюдает запрос -Wait, и ВСЕ фоновые процессы / задания возвращают статус «Завершено», даже если они все еще работают!

Я обнаружил это, когда моя программа C # Explorer используется для открытия окна cmd.exe и PS запускается из этого окна, он также игнорирует запрос -Wait. Похоже, что любая оболочка PowerShell, которая является «задачей win32» cmd.exe, не выполняет запрос ожидания.

Я столкнулся с этим с PowerShell версии 3.0 на Windows 7 / x64

LanDenLabs
источник
5

Я обнаружил, что использование cmd хорошо работает как альтернатива, особенно когда вам нужно передать вывод из вызываемого приложения (особенно, когда оно не имеет встроенного журнала, в отличие от msbuild)

cmd /C "$msbuild $args" >> $outputfile

средний космос
источник
2

Если только OP не использует PowerShell Community Extensions, которые предоставляют командлет Start-Process вместе с множеством других. Если это так, то решение Glennular работает отлично, поскольку оно соответствует позиционным параметрам pscx \ start-process: -path (position 1) -arguments (positon 2).

Кейт Хилл
источник