如何使进程B的子进程C不随非受控父进程A终止(A通过Job对象启动B)
如何使进程B的子进程C不随非受控父进程A终止(A通过Job对象启动B)
这个问题我之前碰到过,核心坑点在于Windows的Job对象有个默认行为:只要进程属于某个Job,它启动的子进程会自动被纳入同一个Job,而且一个进程只能属于一个Job对象——所以你之前尝试给C分配新Job的做法其实根本行不通,因为C已经被自动归到A创建的Job里了,没法再加入其他Job。
下面给你几个可行的解决方案,按推荐程度排序:
方法一:让C直接脱离当前Job(优先尝试)
这个方法的前提是A创建的Job没有禁止进程脱离。你需要在进程B的代码里做两件事:- 先获取当前进程所属的Job句柄(用
GetCurrentJob函数),然后调用SetInformationJobObject,配置JobObjectExtendedLimitInformation结构体,开启JOB_OBJECT_LIMIT_BREAKAWAY_OK或者JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK权限。简单说,前者需要你启动C时加个标志,后者不需要额外操作就能让子进程自动脱离。 - 启动C的时候,如果用的是
JOB_OBJECT_LIMIT_BREAKAWAY_OK,就在CreateProcess的创建参数里加上CREATE_BREAKAWAY_FROM_JOB标志;如果是后者,直接启动就行。这样C就不会被纳入A的Job,A终止时自然不会影响到它。
要是A的Job设置了JOB_OBJECT_LIMIT_NO_BREAKAWAY(禁止脱离),那这个方法就用不了了,得换下面的路子。
- 先获取当前进程所属的Job句柄(用
方法二:找“外部代理”启动C(方法一失效时用)
如果A锁死了Job不让脱离,那就得找个不在这个Job里的进程来帮你启动C:- 用WMI的
Win32_Process.Create方法:WMI创建的进程完全独立,不会继承父进程的Job,非常靠谱。 - 临时创建Windows服务:服务进程运行在独立的系统上下文里,和用户态的Job不搭边,由它启动的C肯定不会受A影响。
- 要是你用的是.NET开发B,还有个偷懒的办法:把
ProcessStartInfo.UseShellExecute设为true,这样C会通过系统的explorer进程启动,而explorer肯定不在A的Job里,自然能避开这个问题。
- 用WMI的
备注:内容来源于stack exchange,提问作者waistcoat1971
相关产品推荐
相关产品推荐

