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

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

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

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

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

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

Какие-либо решения для большего количества выборочного наследования? Я особенно интересуюсь решением, которое позволяет мне конкретно объявлять, какие дескрипторы наследоваться, и все неуказанные дескрипторы не будет наследован, если такое решение будет существовать.

Большое спасибо.

6
задан KevenK 26 February 2010 в 21:17
поделиться

2 ответа

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

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

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

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

3
ответ дан 17 December 2019 в 07:03
поделиться

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

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

1
ответ дан 17 December 2019 в 07:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: