PowerShell - Start-Prozess- und Cmdline-Switches

79

Ich kann das gut laufen lassen:

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

Aber wenn ich diesen Code (unten) ausführe, erhalte ich eine Fehlermeldung:

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

Gibt es eine Möglichkeit, Parameter über den Startprozess an MSBuild zu übergeben? Ich bin offen dafür, den Startprozess nicht zu verwenden. Der einzige Grund, warum ich ihn verwendet habe, war, dass ich den "Befehl" als Variable haben musste.

Wie wird das in Powershell gehandhabt, wenn ich
C: \ WINDOWS \ Microsoft.NET \ Framework \ v3.5 \ MSBuild.exe / v: q / nologo
in einer eigenen Zeile habe?

Sollte ich stattdessen eine eval () -Funktion verwenden?

BuddyJoe
quelle
Alternativen zum Startvorgang finden Sie unter blogs.msdn.com/powershell/archive/2007/01/16/… .
i_am_jorf
Danke Jeffamaphon, dies war auch eine gute Referenzinfo.
BuddyJoe
1
Beachten Sie, dass Start-Process eine neue Funktion in V2 ist. Die Informationen in diesem Beitrag sind sehr gut, aber einige davon sind in V2 nicht mehr wirklich notwendig.
EBGreen
Start-Prozess selbst ist neu in V2? Können Sie etwas näher darauf eingehen? Ich habe keine Maschine mit V1 zum Testen installiert.
BuddyJoe
1
Ich meine nur, dass das Commandlet Start-Process in V1 nicht vorhanden war. In V1 mussten Sie eine der Methoden verwenden, die in dem Blog-Beitrag aufgeführt sind, den Jef verlinkt hat.
EBGreen

Antworten:

124

Sie möchten Ihre Argumente in separate Parameter unterteilen

$msbuild = "C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe"
$arguments = "/v:q /nologo"
start-process $msbuild $arguments 
Glennular
quelle
15
$argsDa ein Variablenname nicht funktioniert, ist er reserviert. Verwenden Sie $argumentsoder irgendetwas anderes stattdessen
Joshcomley
1
Es sieht so aus, als ob die Vorschlagswarteschlange voll ist, aber ich würde den Lesern raten, zu verstehen, dass -ArgumentListnach Zeichenfolgen gesucht wird. Das Beispiel für eine andere Antwort mit durch Kommas getrennten Zeichenfolgen (technisch gesehen ein Array) funktioniert möglicherweise, weil PowerShell sie möglicherweise abrollt, aber wenn ja Wenn Sie eine Argumentliste aus einem Array übergeben möchten, ist es wahrscheinlich am besten, sie vorher in einen String zu "entpacken".
Dragon788
3
@ dragon788, get-help start-processgibt an, dass -ArgumentList erwartetString[]
Asynchronos
60

Mit expliziten Parametern wäre es:

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

EDIT: Anführungszeichen.

EBGreen
quelle
Ich denke, es wäre in Ordnung ohne sie, aber es wäre definitiv in Ordnung mit ihnen, also werde ich es bearbeiten
EBGreen
4
Es scheint zuverlässiger zu sein-ArgumentList ('/v:q','/nologo')
Peter Taylor
1
Powershell ist so ausführlich. git gui &- wie einfach ist das (* nix natürlich)! Im Vergleich zu start-Process git -ArgumentList gui. Ich weiß, ich weiß, nicht hilfreich. Ich habe in letzter Zeit ein bisschen mit Powershell gespielt und viele schöne Dinge; aber die Ausführlichkeit ist ein Killer!
HankCa
1
Nun, es ist nur so ausführlich, wenn Sie es wollen: Start git -args gui funktioniert auch. Mir ist klar, dass dies immer noch ausführlicher ist als * nix. Der Punkt ist, dass, wenn Sie Tab-Vervollständigung und Aliase verwenden, die Anzahl der tatsächlichen Tastenanschläge erheblich abnimmt. Ich werde auch hinzufügen, dass die Ausführlichkeit bedeutet, dass eine Person, die Powershell überhaupt nicht gut kennt, den PS-Befehl lesen und leichter genau verstehen kann, was er tut. Nur ein Unterschied in der Philosophie.
EBGreen
@HankCa,sajb { git gui }
Asynchronos
7

Warnung

Wenn Sie PowerShell in einem von Powershell erstellten cmd.exe-Fenster ausführen, wartet die zweite Instanz nicht mehr auf den Abschluss von Jobs.

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

Führen Sie nun im neuen cmd-Fenster PowerShell erneut aus und starten Sie darin ein zweites cmd-Fenster: cmd2> PowerShell

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

Die zweite Instanz von PowerShell berücksichtigt die Warteanforderung nicht mehr und ALLE Hintergrundprozesse / Jobs geben den Status "Abgeschlossen" zurück, auch wenn sie noch ausgeführt werden!

Ich habe dies festgestellt, als mein C # Explorer-Programm zum Öffnen eines cmd.exe-Fensters verwendet wird und PS in diesem Fenster ausgeführt wird. Außerdem wird die -Wait-Anforderung ignoriert. Es scheint, dass jede PowerShell, bei der es sich um einen 'win32-Job' von cmd.exe handelt, die Warteanforderung nicht erfüllt.

Ich bin mit PowerShell Version 3.0 unter Windows 7 / x64 darauf gestoßen

LanDenLabs
quelle
5

Ich habe festgestellt, dass die Verwendung von cmd als Alternative gut funktioniert, insbesondere wenn Sie die Ausgabe der aufgerufenen Anwendung weiterleiten müssen (insbesondere, wenn im Gegensatz zu msbuild keine integrierte Protokollierung vorhanden ist).

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

Mittelraum
quelle
2

Es sei denn, das OP verwendet PowerShell Community Extensions, die zusammen mit einer Reihe anderer ein Start-Process-Cmdlet bereitstellen. Wenn dies der Fall ist, ist Glennulars Lösung eine Wohltat, da sie mit den Positionsparametern von pscx \ start-process übereinstimmt: -path (Position 1) -arguments (Position 2).

Keith Hill
quelle