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

时间:2015-10-29 20:59:28

标签: c++ windows winapi createprocess

我有一个Windows命令行应用程序child.exe,我希望为其创建一个包装器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...
}

我现在希望在父进程关闭时终止子进程。在another question之后,我使用作业对象来执行此操作:

// 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

将创建的子流程分配给此作业
if(CreateProcessW(...)) {
    AssignProcessToJobObject(ghJob, processInfo.hProcess));
    WaitForSingleObject(processInfo.hProcess, INFINITE);
    ...
} ...

这样做:因为新创建的进程被分配给JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE的作业,所以当父进程因任何原因关闭时,子进程会自动终止。

但这是我的问题:我无法控制child.exe。它产生了自己的子流程(比如grandchild.exe),所以我们有:

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

不幸的是,这个"产生了grandchild.exe"如上所述,将作业对象分配给child.exe时失败。我相信这是因为grandchild.exe继承了我的作业定义,但child.exe尝试将自己的作业定义应用于grandchild.exe并失败,因为在Windows 7上作业可能只与单个作业相关联。 docs for AssignProcessToJobObject表示如果希望创建不从父级继承作业的进程,则在调用CREATE_BREAKAWAY_FROM_JOB时必须使用CreateProcess标志。但问题是这次CreateProcess的调用发生在child.exe内,我无权访问。

任何人都可以想到一个允许child.exe自由生成自己的(大)子进程的解决方案,同时让我可以在child.exe时终止parent.exe关闭了?

1 个答案:

答案 0 :(得分:1)

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

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