如何在Powershell中开始一个比其父母更长的后台工作?

时间:2011-12-15 05:04:03

标签: powershell

请考虑以下代码:

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

父进程退出后台作业将被终止,因此不会发生对cmd.exe的调用。我想写一些类似的代码,这样父母就会立即退出,孩子继续在后台运行。

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

4 个答案:

答案 0 :(得分:14)

您必须开始一个过程:

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

答案 1 :(得分:3)

如果使用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主机进程。

答案 2 :(得分: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

您的脚本将等待脚本块的结束完成。

答案 3 :(得分:1)

如果发现使用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; }

突然在它的父母去世后幸存(可能是因为invoke-command适合在另一台计算机上运行程序,所以父母可以永远无法解决它)