2

I have a Windows command line application child.exe for which I wish to create a wrapper, parent.exe. I do this by spawning the child from the parent using 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...
}

I now want the child process to be terminated when the parent process closes. Following another question, I am using Job Objects to do so:

// 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... */ }
}

I then assign the created child process to this job via AssignProcessToJobObject:

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

This works: Because the newly created process is assigned to a job with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, the child process is automatically terminated when the parent process closes for whatever reason.

But here is my problem: I don't have control over child.exe. It spawns its own sub-processes (say grandchild.exe), so we have:

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

Unfortunately, this "spawning of grandchild.exe" fails when I assign the job object to child.exe as above. I believe this is because grandchild.exe inherits my job definition but child.exe tries to apply its own job definition to grandchild.exe and fails because on Windows 7 a job may only be associated with a single job. The docs for AssignProcessToJobObject say that if one wishes to create processes that do not inherit the job from their parent, one has to use the CREATE_BREAKAWAY_FROM_JOB flag when calling CreateProcess. But the problem is that this call to CreateProcess happens inside child.exe, to which I have no access.

Can anybody think of a solution that allows child.exe to freely spawn its own (grand)child processes, while at the same time making it possible for me to terminate child.exe when parent.exe is closed?

Community
  • 1
  • 1
Michael Herrmann
  • 4,832
  • 3
  • 38
  • 53

1 Answers1

2

You just need to to set the JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag on the job. This flag prevents child processes from being automatically assigned to the job.

Use the SetInformationJobObject function and the JobObjectExtendedLimitInformation option. The flag is set in the MyExtendedLimitInformation.BasicLimitInformation.LimitFlags member.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158