作业对象上的 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.exe
、B.exe
和 C.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 之前 - 会发生啥?