作业对象上的 CloseHandle() 但不终止由 ShellExecute 创建的进程

Posted

技术标签:

【中文标题】作业对象上的 CloseHandle() 但不终止由 ShellExecute 创建的进程【英文标题】:CloseHandle() on a job object but not killing a process created by ShellExecute 【发布时间】:2018-07-30 06:41:16 【问题描述】:

我有 3 个应用程序,A.exeB.exeC.exe

A.exe 使用此代码创建作业对象:

CreateJobObject( NULL, NULL);

然后它使用以下代码创建一个进程:

CreateProcess(NULL,"B.exe",NULL,NULL,NULL,NORMAL_PRIORITY_CLASS|CREATE_BREAKAWAY_FROM_JOB|CREATE_SUSPENDED,NULL,NULL,&startupInfo,&processInformation);

最后,它将进程添加到作业对象中。

B.exe 在完成其任务之前使用ShellExecute()C.exe 创建一个进程。

C.exe 预计需要 2-3 分钟才能完成其任务。但是随着B.exe 的完成,不知何故C.exe 也被杀死了。我猜是因为我在作业对象上使用了CloseHandle()

如何避免在没有句柄泄漏的情况下杀死C.exe

更新: 我用过

jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE|JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION; 

用于创建作业对象。

【问题讨论】:

简单地关闭作业句柄不会杀死作业中的活动进程,除非作业通过SetInformationJobObject() 启用了JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 标志。另一种选择是将B.exe 改为使用CreateProcess()(无论如何你都应该这样做),这样你就可以使用它的CREATE_BREAKAWAY_FROM_JOB 标志。 Read the documentation 了解更多详情。 是的,我用过 jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE|JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION; 嗯,这是应该包含的重要信息。 【参考方案1】:

需要使用附加标志 JOB_OBJECT_LIMIT_BREAKAWAY_OK 创建作业对象,以允许在作业对象之外创建子进程。

jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE|JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION|JOB_OBJECT_LIMIT_BREAKAWAY_OK;

然后宁可使用

shellexecute()

需要按照#Remy Lebeau 的建议使用 CREATE_BREAKAWAY_FROM_JOB 创建触发 C.exe 的子进程,以在作业之外启动进程。

CreateProcess(NULL,"C.exe",NULL,NULL,NULL,NORMAL_PRIORITY_CLASS|CREATE_BREAKAWAY_FROM_JOB|CREATE_SUSPENDED,NULL,NULL,&startupInfo,&processInformation);

然后为了避免使用句柄泄漏

CloseHandle(processInformation.hProcess);
CloseHandle(processInformation.hThread);

【讨论】:

以上是关于作业对象上的 CloseHandle() 但不终止由 ShellExecute 创建的进程的主要内容,如果未能解决你的问题,请参考以下文章

互斥体上的 CloseHandle,在 ReleaseMutex 之前 - 会发生啥?

VC++ 线程同步 总结

预习作业3

改善程序与设计的55个具体做法 day6

java中如何关闭一个窗口就完全释放它所占的资源但不终止整个程序(程序由多个窗口)

进程考试