2011-12-15 13 views
10

考虑下面的代码:如何在Powershell中启动后台作业,使其超过父级?

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

当父退出,所以调用CMD.EXE永远不会发生的后台作业被杀害。我想写一些类似的代码,以便父母立即退出,并且孩子继续在后台运行。

如果可能,我想将所有内容都放在一个脚本中。

回答

9

您必须启动一个进程:

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

你也可以那样做

$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 

你的脚本将等待脚本块的年底完成。

+2

这与使用等待工作不一样吗? – manojlds 2011-12-15 16:20:31

0

如果发现使用Invoke-Command能够绕过后台作业随其父节点而死的限制。好的是,语法与start-job几乎相同,所以scriptblock可以保持原样。

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

只会变成

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

,突然生存死亡的它的父(可能是因为调用命令适合在另一台计算机上运行的程序,以便家长可以从来不管它)

0

如果您使用Start-Process,则创建一个新的子进程,其中的powershell会话作为其父进程。如果您终止启动它的PowerShell父进程,则新进程将被孤立并继续运行。它将,但是,如果不杀你父母的进程树

Start-Process -FilePath notepad.exe 

生存Powershell的无法启动其进程树之外的新的独立进程为您服务。但是,这可以在Windows中使用CreateProcess完成,并且此功能通过WMI公开。幸运的是,你可以调用从PowerShell中:

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

这样一来,新的进程也将继续运行,如果进程树被杀死了,因为新的进程没有你的PowerShell会话作为父母,但WMI主机进程。