PowerShell - przełączniki Start-Process i Cmdline

79

Mogę uruchomić to dobrze:

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

Ale kiedy uruchamiam ten kod (poniżej), pojawia się błąd:

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

Czy istnieje sposób przekazywania parametrów do programu MSBuild przy użyciu procesu startowego? Jestem otwarty na to, że nie używam start-process, jedynym powodem, dla którego go użyłem, było posiadanie „polecenia” jako zmiennej.

Kiedy mam
C: \ WINDOWS \ Microsoft.NET \ Framework \ v3.5 \ MSBuild.exe / v: q / nologo
w jednym wierszu, jak to jest obsługiwane w programie Powershell?

Czy powinienem zamiast tego używać jakiejś funkcji eval ()?

BuddyJoe
źródło
Zobacz blogs.msdn.com/powershell/archive/2007/01/16/…, aby zapoznać się z alternatywami do uruchamiania procesu.
i_am_jorf,
Dzięki jeffamaphone, to też była dobra informacja referencyjna.
BuddyJoe,
1
Pamiętaj, że Start-Process to nowa funkcja w wersji 2. Informacje zawarte w tym poście są bardzo dobre, ale niektóre z nich nie są już potrzebne w wersji V2.
EBGreen
Sam proces uruchamiania jest nowy w wersji 2? Czy możesz trochę rozwinąć? Nie mam żadnej maszyny z zainstalowaną wersją V1 do przetestowania.
BuddyJoe,
1
Chodzi mi tylko o to, że polecenie Start-Process nie istniało w wersji V1. W wersji 1 musiałeś użyć jednej z metod wymienionych w poście na blogu, do którego linkował Jef.
EBGreen

Odpowiedzi:

124

będziesz chciał podzielić swoje argumenty na osobne parametry

$msbuild = "C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe"
$arguments = "/v:q /nologo"
start-process $msbuild $arguments 
Glennular
źródło
15
$argsponieważ nazwa zmiennej nie działa, jest zarezerwowana. $argumentsZamiast tego użyj lub cokolwiek innego
joshcomley,
1
Wygląda na to, że kolejka sugestii jest pełna, ale radziłbym czytelnikom zrozumieć, że -ArgumentListszuka ciągów znaków, więc przykład innej odpowiedzi z ciągami znaków oddzielonymi przecinkami (technicznie tablicą) może działać z powodu tego, jak potencjalnie PowerShell ją rozwija, ale jeśli tak chcąc przekazać listę argumentów z tablicy, prawdopodobnie najlepiej jest ją wcześniej „rozpakować” do łańcucha.
dragon788
3
@ dragon788, get-help start-processwskazuje, że -ArgumentList oczekujeString[]
asynchronos
60

Używając jawnych parametrów, byłoby to:

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

EDYCJA: cytaty.

EBGreen
źródło
Myślę, że bez nich byłoby w porządku, ale na pewno byłoby w porządku z nimi, więc go wyedytuję
EBGreen
4
Wydaje się, że jest bardziej niezawodny w użyciu-ArgumentList ('/v:q','/nologo')
Peter Taylor
1
Powershell jest tak gadatliwy. git gui &- jakie to proste (* nix oczywiście)! W porównaniu do start-Process git -ArgumentList gui. Wiem, wiem, nie pomocne. Ostatnio trochę bawiłem się Powershell i wiele fajnych rzeczy; ale gadatliwość jest zabójcza!
HankCa
1
Cóż, jest to tylko takie gadatliwe, jeśli chcesz, aby było: start git -args gui też działa. Zdaję sobie sprawę, że jest to jeszcze bardziej szczegółowe niż * nix. Chodzi o to, że jeśli używasz uzupełniania tabulatorów i aliasów, liczba rzeczywistych naciśnięć klawiszy znacznie spada. Dodam również, że gadatliwość oznacza, że ​​osoba, która w ogóle nie zna dobrze PowerShell, mogłaby przeczytać polecenie PS i łatwiej zrozumieć, co dokładnie robi. Tylko różnica w filozofii.
EBGreen
@HankCa,sajb { git gui }
asynchronos
7

Ostrzeżenie

Jeśli uruchomisz PowerShell z okna cmd.exe utworzonego przez Powershell, drugie wystąpienie nie będzie już czekać na zakończenie zadań.

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

Teraz z nowego okna cmd uruchom ponownie PowerShell iw nim uruchom drugie okno cmd: cmd2> PowerShell

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

Drugie wystąpienie programu PowerShell nie honoruje już żądania -Wait, a WSZYSTKIE procesy / zadania w tle zwracają stan „Ukończono”, nawet jeśli nadal działają!

Odkryłem to, gdy mój program C # Explorer jest używany do otwierania okna cmd.exe i PS jest uruchamiany z tego okna, ignoruje również żądanie -Wait. Wygląda na to, że żaden program PowerShell, który jest „zadaniem win32” programu cmd.exe, nie spełnia żądania oczekiwania.

Natknąłem się na to z PowerShell w wersji 3.0 w systemie Windows 7 / x64

LanDenLabs
źródło
5

Zauważyłem, że użycie cmd działa dobrze jako alternatywa, zwłaszcza gdy musisz przesłać dane wyjściowe z wywoływanej aplikacji (szczególnie, gdy nie ma ona wbudowanego logowania, w przeciwieństwie do msbuild)

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

w środku przestrzeni
źródło
2

Chyba że OP korzysta z rozszerzeń społeczności programu PowerShell, które zapewniają cmdlet Start-Process wraz z kilkoma innymi. W takim przypadku rozwiązanie Glennulara działa świetnie, ponieważ pasuje do parametrów pozycyjnych pscx \ start-process: -path (pozycja 1) -arguments (pozycja 2).

Keith Hill
źródło