WindowsAPI工作Objects:不要传给孙子

Windows API Job Objects: Don't pass on to grandchildren

我有一个 Windows 命令行应用程序 child.exe,我想为其创建一个包装器 parent.exe。我通过使用 CreateProcess:

从 parent 生成 child 来做到这一点
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...
}

我现在希望 child 进程在 parent 进程关闭时终止。在 another question 之后,我正在使用 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:

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

这行得通:因为新创建的进程被分配给 JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 的作业,所以当 parent 进程出于任何原因关闭时,child 进程自动终止。

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

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

不幸的是,当我如上所述将作业 object 分配给 child.exe 时,这个 "spawning of grandchild.exe" 失败了。我相信这是因为 grandchild.exe 继承了我的工作定义,但 child.exe 试图将其自己的工作定义应用于 grandchild.exe 但失败了,因为在 Windows 7 上,工作可能只与一份工作。 docs for AssignProcessToJobObject 表示如果希望创建不从 parent 继承作业的进程,则必须在调用 CreateProcess 时使用 CREATE_BREAKAWAY_FROM_JOB 标志。但问题是对 CreateProcess 的调用发生在 child.exe 内部,我无法访问它。

谁能想出一个解决方案,允许 child.exe 自由生成自己的(大)child 进程,同时让我可以终止 child.exe parent.exe 何时关闭?

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

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