问题 我怎样才能在Powershell中开始一个比其父母更长的后台工作?


请考虑以下代码:

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

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

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


1002
2017-12-15 05:04


起源



答案:


你必须开始一个过程:

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

10
2017-12-15 07:56





你也可以这样做

$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

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


1
2017-12-15 09:36



这与使用Wait-job不一样吗? - manojlds
你可能是对的我会测试! - JPBlanc
我想说的是,我不认为OP想要这样。他们想要的是,当父母关闭(并且应该关闭)但是不应该等待工作时,工作仍然运行。但我可能错了:) - manojlds
我不知道,其实我不介意,我只是换个方式,等待工作更短,它可以帮助别人。 - JPBlanc


答案:


你必须开始一个过程:

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

10
2017-12-15 07:56





你也可以这样做

$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

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


1
2017-12-15 09:36



这与使用Wait-job不一样吗? - manojlds
你可能是对的我会测试! - JPBlanc
我想说的是,我不认为OP想要这样。他们想要的是,当父母关闭(并且应该关闭)但是不应该等待工作时,工作仍然运行。但我可能错了:) - manojlds
我不知道,其实我不介意,我只是换个方式,等待工作更短,它可以帮助别人。 - JPBlanc


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

并突然幸免于它的父亲的死亡(可能是因为调用命令适合在另一台计算机上运行程序,所以父母可以永远不重要)


1
2017-08-30 12:30



它似乎 调用命令 要求 远程要求 也适用于当地的业务。 - CodeFox


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


1
2017-12-07 21:08