CreateProcess, так что дочерний процесс убивается, когда родитель убит?

Есть ли способ вызвать CreateProcess, чтобы убить родительский процесс автоматически убил дочерний процесс?

Возможно, используя Создать флаги процесса?

Изменить
Решением является создание объекта задания, размещение родителя и дочернего объекта в объекте задания. Когда его родитель убит, ребенок убит. Я получил код отсюда: Убить дочерний процесс, когда родительский процесс убит Обратите внимание на комментарий @wilx о наследуемых дескрипторах.

Ответ 1

Использование заданий как Нил говорит, это ИМХО лучший способ. Вы можете убить дочерние процессы, когда процесс владения работой умирает, установив JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE в объект задания с помощью SetInformationJobObject(). Обработчик объекта задания будет закрыт, когда ваш родительский процесс завершит/умрет. Для этого важно, чтобы дескриптор задания не, унаследованный дочерними процессами. Если вы хотите отследить также процессы grand-child, вам придется приостановить дочерние процессы, добавить их в свой объект задания и только затем запустить их.

Ответ 2

Лучшее, что вы можете сделать, это поставить оба процесса в одну и ту же работу, чтобы убить работу, убивая оба процесса.

Ответ 3

Вам нужно, чтобы дочерний процесс был убит или просто обнаружил выход родительского процесса, чтобы он мог закончить чистоту? Родительский процесс может создать наследуемый дескриптор для себя, который потом может передать дочернему элементу WaitForMultipleObjects(Ex) вместе со своими собственными объектами.

Если дочерний процесс не написан специально для этого, вы можете прикрепить его stdin к каналу, другой конец которого принадлежит родительскому процессу. Если родитель умирает, труба автоматически закрывается.

Это близко соответствует поведению Unix, в котором ребенок не убивается, когда его родитель умирает, он обычно выходит в ответ на SIGHUP (но он может обрабатывать этот сигнал и осуществлять любое поведение). В Linux родительский PID сироты изменяется на 1 (init).

Ответ 4

Я полагаю, что DEBUG_PROCESS или DEBUG_ONLY_THIS_PROCESS сделает это как почти случайный побочный эффект. Windows не создает процессы в дереве, как это делают Unix-подобные системы.

Ответ 5

Не знаю о Windows, но это будет работать на Linux: prctl (PR_SET_PDEATHSIG, SIGHUP);

Ответ 6

Другой подход

Не полезно во всех ситуациях, однако у меня был один конкретный сценарий, когда приложение полностью контролировало дочерний процесс. Для связи и перехвата API требовалась DLL-инъекция, поэтому DLL запускается в реальных дочерних процессах, чтобы сообщить родителям.

Примечание: Теперь это не для награды за творчество. Фон здесь: Приложение, которое необходимо было обернуть, однако это было устаревшее приложение и не могло ни быть изменено, ни переписано удовлетворительным образом. Нам нужно было поддерживать работу этой системы, все еще перехватывая ее.

Кроме того, дочерний процесс был плохо написан, немедленно запускался, а затем завершался, поэтому родительский процесс на самом деле не нашего основного приложения.

Если вы управляете дочерними процессами и имеете вложенную DLL в любом случае, вы можете расширить эту DLL, контролируя родительский процесс, чтобы проверить, запущен ли он. Если нет, ExitProcess.

Если вам не нужна DLL в дочернем процессе, другие решения, скорее всего, намного лучше.


Вы можете передать parentProcessID через, например, раздел реестра, который вы используете своим приложением уже. Или вы можете передать командную строку, если это не прерывает дочерний процесс.

Это должно выполняться в своем потоке. В моей DLL было два потока: этот код здесь и код управления и связи.

DLL

bool IsProcessRunning(HANDLE hProcess)
{
    DWORD exitCode;
    GetExitCodeProcess(hProcess, &exitCode);
    return exitCode == STILL_ACTIVE;
}

bool WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
{
    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        int parentProcessID = [...]

        HANDLE parentProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, parentProcessID);
        while (IsProcessRunning(parentHandle)) Sleep(100);
        ExitProcess(0);
    }

    return true;
}