Объекты Windows API Job: не передавайте внукам

У меня есть приложение командной строки 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...
}

Теперь я хочу, чтобы дочерний процесс завершался при закрытии родительского процесса. Следуя другому вопросу, я использую Объекты задания для этого:

// 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 задание может быть связано только с одним заданием. Документы для _17 _ скажите, что если кто-то хочет создать процессы, которые не наследуют задание от своего родителя, он должен использовать флаг CREATE_BREAKAWAY_FROM_JOB при вызове CreateProcess. Но проблема в том, что этот вызов CreateProcess происходит внутри child.exe, к которому у меня нет доступа.

Может ли кто-нибудь придумать решение, которое позволяет child.exe свободно порождать свои собственные (большие) дочерние процессы, и в то же время дает мне возможность завершить child.exe, когда parent.exe закрыт?


person Michael Herrmann    schedule 29.10.2015    source источник


Ответы (1)


Вам просто нужно установить флаг JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK на задании. Этот флаг предотвращает автоматическое назначение дочерним процессам заданию.

Используйте функцию SetInformationJobObject и вариант JobObjectExtendedLimitInformation. Флаг установлен в члене MyExtendedLimitInformation.BasicLimitInformation.LimitFlags.

person Harry Johnston    schedule 29.10.2015