Windows API作业对象:不要传递给孙子们

我有一个Windows命令行应用程序child.exe ,我希望为其创build一个包装器parent.exe 。 我通过使用CreateProcess从父项产生子项来完成此操作:

 int wmain(int argc, WCHAR *argv[]) { STARTUPINFO startupInfo = createStartupInfo(); PROCESS_INFORMATION processInfo = {0}; if(CreateProcessW( L"C:\\child.exe", NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &processInfo )) { WaitForSingleObject(processInfo.hProcess, INFINITE); CloseHandle(processInfo.hThread); CloseHandle(processInfo.hProcess); return 0; } else { return -1; } } STARTUPINFO createStartupInfo() { // Create and return a STARTUPINFO structure... } 

我现在想要在父进程closures时终止subprocess。 接下来的另一个问题是 ,我使用Job Objects来做到这一点:

 // Create and initialise the job object: HANDLE ghJob = CreateJobObject(NULL, NULL); if (ghJob == NULL) { /* Error handling... */ } else { JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 }; // Configure all child processes associated with the // job to terminate when the parent closes: jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; if (! SetInformationJobObject( ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli) )) { /* Error handling... */ } } 

然后通过AssignProcessToJobObject将创build的subprocess分配给这个工作:

 if(CreateProcessW(...)) { AssignProcessToJobObject(ghJob, processInfo.hProcess)); WaitForSingleObject(processInfo.hProcess, INFINITE); ... } ... 

这是有效的:因为新创build的进程被分配到JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE的作业,当父进程因任何原因closures时,subprocess会自动终止。

但是,这是我的问题 :我没有控制child.exe 。 它产生了自己的subprocess(如grandchild.exe ),所以我们有:

 parent.exe -> child.exe -> grandchild.exe 

不幸的是,当我将作业对象分配给child.exe时,这个“产生的grandchild.exe ”失败。 我相信这是因为grandchild.exeinheritance我的作业定义,但是child.exe尝试将自己的作业定义应用于grandchild.exe并失败,因为在Windows 7上作业可能只与单个作业关联。 AssignProcessToJobObject的文档说,如果希望创build不从父类inheritance作业的进程,则在调用CreateProcess时必须使用CREATE_BREAKAWAY_FROM_JOB标志。 但问题是这个调用CreateProcess发生在child.exe ,我没有访问权限。

任何人都可以想到一个解决scheme,它允许child.exe自由地产生自己的(大)subprocess,同时使我可以在parent.execlosures时终止child.exe吗?

您只需要在作业上设置JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK标志。 该标志防止子进程被自动分配给作业。

使用SetInformationJobObject函数和JobObjectExtendedLimitInformation选项。 该标志在MyExtendedLimitInformation.BasicLimitInformation.LimitFlags成员中设置。