PowerShell: conmutadores de inicio de proceso y línea de comandos

79

Puedo ejecutar esto bien:

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

Pero cuando ejecuto este código (a continuación), aparece un error:

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

¿Hay alguna forma de pasar parámetros a MSBuild usando start-process? Estoy abierto a no usar start-process, la única razón por la que lo usé fue que necesitaba tener el "comando" como variable.

Cuando tengo
C: \ WINDOWS \ Microsoft.NET \ Framework \ v3.5 \ MSBuild.exe / v: q / nologo
en una línea por sí solo, ¿cómo se maneja eso en Powershell?

¿Debería usar algún tipo de función eval () en su lugar?

BuddyJoe
fuente
Consulte blogs.msdn.com/powershell/archive/2007/01/16/… para conocer las alternativas al proceso de inicio.
i_am_jorf
Gracias jeffamaphone, esta también fue una buena información de referencia.
BuddyJoe
1
Tenga en cuenta que Start-Process es una característica nueva en V2. La información en esa publicación es muy buena, pero parte de ella ya no es realmente necesaria en la V2.
EBGreen
¿El proceso de inicio es nuevo en V2? ¿Puedes elaborar un poco? No tengo ninguna máquina con V1 instalada para probar.
BuddyJoe
1
Solo quiero decir que el comando Start-Process no existía en V1. En V1, tenía que usar uno de los métodos enumerados en la publicación del blog que Jef vinculó.
EBGreen

Respuestas:

124

vas a querer separar tus argumentos en parámetros separados

$msbuild = "C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe"
$arguments = "/v:q /nologo"
start-process $msbuild $arguments 
Glennular
fuente
15
$argscomo un nombre de variable no funciona, está reservado. Use $argumentso cualquier otra cosa en su lugar
joshcomley
1
Parece que la cola de sugerencias está llena, pero recomendaría a los lectores que comprendan que -ArgumentListestá buscando una cadena, por lo que el ejemplo en otra respuesta con cadenas separadas por comas (técnicamente una matriz) puede funcionar debido a cómo PowerShell lo desenrolla potencialmente, pero si lo está Si busca pasar una lista de argumentos desde una matriz, probablemente sea mejor "descomprimirla" en una cadena de antemano.
dragon788
3
@ dragon788, get-help start-processindica que -ArgumentList esperaString[]
asynchronos
60

Usando parámetros explícitos, sería:

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

EDITAR: comillas.

EBGreen
fuente
Creo que estaría bien sin ellos, pero definitivamente estaría bien con ellos, así que lo
editaré
4
Parece ser más confiable de usar-ArgumentList ('/v:q','/nologo')
Peter Taylor
1
Powershell es TAN detallado. git gui &- ¡Qué simple es eso (* nix por supuesto)! Comparado con start-Process git -ArgumentList gui. Lo sé, lo sé, no es útil. He estado jugando con Powershell un poco últimamente y muchas cosas buenas; ¡Pero la verbosidad es un asesino!
HankCa
1
Bueno, es solo así de detallado si quieres que sea: start git -args gui también funciona. Me doy cuenta de que esto es aún más detallado que * nix. El punto es que si usa la finalización de tabulación y los alias, el número de pulsaciones de teclas reales se reduce considerablemente. También agregaré que la verbosidad significa que una persona que no conoce bien powershell en absoluto podría leer el comando PS y entender más fácilmente lo que está haciendo exactamente. Solo una diferencia en filosofía.
EBGreen
@HankCa,sajb { git gui }
asynchronos
7

Advertencia

Si ejecuta PowerShell desde una ventana cmd.exe creada por Powershell, la segunda instancia ya no espera a que se completen los trabajos.

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

Ahora, desde la nueva ventana de cmd, ejecute PowerShell nuevamente y dentro de ella inicie una segunda ventana de cmd: cmd2> PowerShell

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

La segunda instancia de PowerShell ya no respeta la solicitud -Wait y TODOS los procesos / trabajos en segundo plano devuelven el estado 'Completado' incluso si todavía se están ejecutando.

Descubrí esto cuando mi programa C # Explorer se usa para abrir una ventana cmd.exe y PS se ejecuta desde esa ventana, también ignora la solicitud -Wait. Parece que cualquier PowerShell que sea un 'trabajo win32' de cmd.exe no cumple con la solicitud de espera.

Me encontré con esto con PowerShell versión 3.0 en Windows 7 / x64

LanDenLabs
fuente
5

Descubrí que usar cmd funciona bien como una alternativa, especialmente cuando necesita canalizar la salida de la aplicación llamada (especialmente cuando no tiene un registro integrado, a diferencia de msbuild)

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

espacio intermedio
fuente
2

A menos que el OP esté utilizando PowerShell Community Extensions, que proporciona un cmdlet Start-Process junto con muchos otros. Si este es el caso, entonces la solución de Glennular funciona muy bien, ya que coincide con los parámetros posicionales de pscx \ start-process: -path (position 1) -arguments (positon 2).

Keith Hill
fuente