Выберите, какие дескрипторы наследуются дочерним процессом

StackOverflow https://stackoverflow.com/questions/2344887

Вопрос

При создании дочернего процесса на C ++ с использованием Windows API можно разрешить наследование дескрипторов от родительского к дочернему.В примере Microsoft "Создание дочернего процесса с перенаправленным вводом и выводом", перенаправляя std дочернего процесса на вход / выход в каналы, созданные родительским процессом, необходимо разрешить наследование для использования каналов перенаправления.

Я работаю над небольшим демонстрационным классом, который запускает внешний исполняемый файл, считывает выходные данные, а затем отправляет их обратно вызывающему (который записывает возвращенные выходные данные в файл).Я пытаюсь встроить функцию тайм-аута, при которой она будет блокироваться только на определенное время перед вызовом TerminateProcess() о ребенке и продолжении жизни.

Однако я обнаружил, что, разрешив наследование дескриптора, дочерний процесс также имеет дескриптор (видимый с Обозреватель процессов) в выходной файл.Я не хочу, чтобы дочерний процесс получал этот дескриптор, но родительский в данном случае (этот демонстрационный класс) также не знает об этом дескрипторе, поэтому в настоящее время я не могу использовать SetHandleInformation() отменить пометку выходного файла специально для исключения его из наследования.

Я уверен, что должен быть лучший способ наследовать Только конкретные дескрипторы, которые я хочу, не допуская "общего" наследования, которое передает непреднамеренные и нежелательные дескрипторы.К сожалению, я не смог найти решение, просмотрев столько связанных статей MSDN, сколько смог найти, и загуглив себя в состояние уныния.

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

Есть какие-нибудь решения для более избирательного наследования?Меня особенно интересует решение, которое позволяет мне конкретно указывать, какие дескрипторы наследовать, и все неуказанные дескрипторы не будут наследоваться, если такое решение существует.

Сердечно благодарю вас.

Это было полезно?

Решение

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

Мне кажется, что ваш класс, создающий процесс, не должен пытаться предугадать своего вызывающего, который уже открыл файл.

Однако, если у вас есть специальные знания о том, какие именно дескрипторы необходимы новому процессу, то начиная с Windows Vista, существует механизм для указания того, какие дескрипторы следует наследовать.Когда вы будете готовы позвонить CreateProcess, использовать STARTUPINFOEX структура вместо обычной STARTUPINFO.В нем есть lpAttributeList Участник.Выделите и инициализируйте его, а затем используйте UpdateProcThreadAttribute с PROC_THREAD_ATTRIBUTE_HANDLE_LIST чтобы задать список дескрипторов, которые будут наследоваться.Все дескрипторы должны быть наследуемыми, и вам все равно нужно указать bInheritHandles = true когда ты позвонишь CreateProcess.Вам также необходимо включить EXTENDED_STARTUPINFO_PRESENT в dwCreationFlags параметр. Рэймонд Чен продемонстрировал эту технику в статье в 2011 году.

Если эта добавленная функциональность вам недоступна, то вы, конечно, можете попробовать [перечислить все открытые дескрипторы вашей программы] и задать все их свойства наследования с помощью SetHandleInformation, но это, по-видимому, выходит за рамки функции, в задачу которой входит создание дочерних процессов.Пусть код, создающий дескрипторы, беспокоится о том, должны ли они быть наследуемыми.

Другие советы

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

Если этот флаг установлен, дочерний процесс, созданный с параметром bInheritHandles CreateProcess, для которого установлено значение TRUE, унаследует дескриптор объекта.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top