2011-12-15 7 views
10

Si consideri il seguente codice:Come posso avviare un lavoro in background in Powershell che sopravvive al suo genitore?

start-job -scriptblock { sleep 10; cmd /c set > c:\env.txt; } 
exit 

Il processo in background viene ucciso quando le uscite genitore, quindi la chiamata al cmd.exe non si verifica mai. Vorrei scrivere un codice simile, in modo tale che il genitore esca immediatamente e il bambino continui a correre in background.

Mi piacerebbe conservare tutto in uno script, se possibile.

risposta

9

Si dovrà avviare un processo:

start-process powershell -ArgumentList "sleep 10; cmd /c set > c:\env.txt" -WindowStyle hidden 
1

È anche possibile fare in quel modo

$a = start-job -scriptblock { sleep 10; cmd /c set > c:\env.txt; } 
Register-ObjectEvent -InputObject $a -EventName StateChanged -SourceIdentifier "finished" 
$b = Wait-Event -SourceIdentifier "finished" 
exit 

Lo script attenderà la fine della scriptblock per terminare.

+2

Non sarebbe lo stesso che usare Wait-job? – manojlds

+0

Probabilmente hai ragione, proverò! – JPBlanc

+0

Quello che stavo cercando di dire era, non credo che l'OP lo voglia. Quello che vogliono è che il lavoro sia ancora in esecuzione quando il genitore chiude (e dovrebbe chiudere) ma non dovrebbe aspettare il lavoro. Ma potrei sbagliarmi :) – manojlds

0

Se è stato rilevato che l'utilizzo di Invoke-Command è stato in grado di ignorare la restrizione che il processo in background muore con il relativo genitore. La cosa bella è che la sintassi è quasi la stessa di quella del lavoro iniziale, quindi lo scriptblock può essere mantenuto così com'è.

start-job -scriptblock { sleep 10; cmd /c set > c:\env.txt; } 

sarebbe solo trasformarsi in

Invoke-Command -ComputerName . -AsJob -scriptblock { sleep 10; cmd /c set > c:\env.txt; } 

e improvvisamente sopravvivere alla morte del suo genitore (probabilmente perché Invoke-Command è in grado di eseguire programmi su un altro computer in modo che il genitore può mai importare a esso)

0

Se si utilizza Start-Process, si crea un nuovo processo figlio che ha la sessione di PowerShell come processo padre. Se si uccide il processo genitore PowerShell all'avvio, il nuovo processo sarà orfano e continuerà a essere in esecuzione. Sarà, tuttavia, non sopravvivere se uccidi albero processo del genitore

Start-Process -FilePath notepad.exe 

PowerShell non può iniziare un nuovo processo indipendente al di fuori del suo albero processo per voi. Tuttavia, ciò può essere fatto in Windows utilizzando CreateProcess e questa funzionalità è esposta tramite WMI. Fortunatamente, è possibile chiamare tale da PowerShell:

Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList notepad.exe 

In questo modo, il nuovo processo si continua a funzionare se l'albero processo viene ucciso, perché il nuovo processo non ha la sessione di PowerShell come genitore, ma il processo host WMI.

Problemi correlati