2009-11-16 51 views
135

Tengo un script de PowerShell 1.0 para simplemente abrir un montón de aplicaciones. La primera es una máquina virtual y las otras son aplicaciones de desarrollo. Quiero que la máquina virtual termine de arrancar antes de que se abra el resto de las aplicaciones.¿Cómo decirle a PowerShell que espere a que termine cada comando antes de comenzar el siguiente?

En bash tan sólo pudiera decir "cmd1 && cmd2"

Esto es lo que tengo ...

C:\Applications\VirtualBox\vboxmanage startvm superdooper 
    &"C:\Applications\NetBeans 6.5\bin\netbeans.exe" 

Respuesta

235

Normalmente, los comandos internos PowerShell esperar antes de comenzar el siguiente comando. Una excepción a esta regla es EXE externo basado en subsistema de Windows. El primer truco es Out-Null tubería para de este modo:

Notepad.exe | Out-Null 

PowerShell va a esperar hasta que el proceso se ha salido Bloc de notas antes de continuar. Eso es ingenioso pero algo sutil a la hora de leer el código. También puede utilizar Puesta en proceso con el parámetro -Espera:

Start-Process <path to exe> -NoNewWindow -Wait 

Si está utilizando la versión de Extensiones de la comunidad de PowerShell es:

$proc = Start-Process <path to exe> -NoWindow 
$proc.WaitForExit() 

Otra opción en PowerShell 2.0 es utilizar un trabajo en segundo plano :

$job = Start-Job { invoke command here } 
Wait-Job $job 
Receive-Job $job 
+1

Mi mal. Start-Process -Wag funciona muy bien, pero ahora veo que esto no es lo que estaba buscando ... En realidad estoy tratando de esperar hasta que el vm termine de arrancar. Me imagino que va a ser difícil. Supongo que tendré que buscar un hilo nuevo para eso. Gracias pero. –

+3

Brillante, '| out-null' hizo exactamente lo que necesitaba. Intenté usar 'Start-Job', pero como estoy pasando los resultados de las funciones como parámetros, me dio un pequeño skitzoid, así que no pude usar la última sugerencia ... – jcolebrand

+4

Como nota al margen, si necesita Pase múltiples argumentos con '-ArgumentList', sepárelos con comas como''ArgumentList/D = test,/S'. – sschuberth

35

Además de utilizar Start-Process -Wait, canalizando el resultado de un ejecutable hará Powershell espera. Dependiendo de la necesidad, habitualmente conectaré a Out-Null, Out-Default, Out-String o Out-String -Stream. Here es una larga lista de algunas otras opciones de salida.

# Saving output as a string to a variable. 
$output = ping.exe example.com | Out-String 

# Filtering the output. 
ping stackoverflow.com | where { $_ -match '^reply' } 

# Using Start-Process affords the most control. 
Start-Process -Wait SomeExecutable.com 

no se pierda los operadores de estilo/Bash CMD que se hace referencia (&, & &, ||). Es parece que tenemos que ser more verbose with Powershell.

+0

¡Esta es una solución increíblemente buena si necesita analizar la salida! –

5

Si utiliza Start-Process <path to exe> -NoNewWindow -Wait

También puede utilizar la opción -PassThru hacerse eco de salida.

3

Algunos programas no pueden procesar la secuencia de salida muy bien, usando la tubería al Out-Null no puede bloquearla.
Y Start-Process necesita el interruptor -ArgumentList para pasar argumentos, no tan conveniente.
También hay otro enfoque.

$exitCode = [Diagnostics.Process]::Start(<process>,<arguments>).WaitForExit(<timeout>) 
+1

¿Cómo funcionan los argumentos múltiples en esa llamada? ¿cómo están delimitados? ¿cómo se maneja una cadena anidada que escapa? ty! – AnneTheAgile

+1

@AnneTheAgile [doc] (http://msdn.microsoft.com/en-us/library/h6ak8zt5 (v = vs.110) .aspx) use el espacio para separar los argumentos, para el escape de char use la barra inversa – ifree

+0

ty @free , ¡Obtuve el test completo para correr de esa manera! Usé comillas simples alrededor de la lista de argumentos delimitados por espacios. [1]; pero ahora echo $ exitcode = false, que no era mi código de retorno del proceso? [1] $ exitCode = [Diagnostics.Process] :: Start ("c: \ Archivos de programa (x86) \ SmartBear \ TestComplete 10 \ Bin \ TestComplete.exe", "" c: \ Users \ ME \ Documents \ TestComplete 10 Proyectos \ hig4TestProject1 \ hig4TestProject1.pjs "/ run/project: myProj/test:" KeywordTests | zTdd1_Good "/ exit ') .WaitForExit (60) – AnneTheAgile

9

Sólo tiene que utilizar "Espera-proceso":

"notepad","calc","wmplayer" | ForEach-Object {Start-Process $_} | Wait-Process ;dir 

trabajo está hecho

1

Incluyendo la opción -NoNewWindow me da un error: Start-Process : This command cannot be executed due to the error: Access is denied.

La única manera de que pudiera conseguirlo para trabajar era llamar:

Start-Process <path to exe> -Wait 
Cuestiones relacionadas