При создании дочернего процесса в C++ с помощью Windows API можно позволить наследование дескрипторов от родителя до ребенка. В примере Microsoft "Создание Дочернего процесса с Перенаправленным Вводом и выводом", перенаправляя станд. дочернего процесса в / к каналам, созданным родителем, необходимо позволить наследованию для каналов перенаправления быть применимым.
Я работаю над маленьким демонстрационным классом, который запускает внешний исполняемый файл, читает вывод и затем плюется им назад вызывающей стороне (кто записывает возвращенный вывод в файл). Я пытаюсь создать в функции тайм-аута, где она только заблокируется для определенного количества времени перед вызовом 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
, но, похоже, это выходит за рамки область действия функции, задачей которой является создание дочерних процессов. Пусть код, создающий дескрипторы, заботится о том, должны ли они быть наследуемыми.
Вы можете использовать SetHandleInformation , чтобы очистить бит HANDLE_FLAG_INHERIT
в выходном дескрипторе, это предотвратит дочерний процесс от наследования.
Если этот флаг установлен, дочерний процесс, созданный с параметром bInheritHandles CreateProcess, установленным в TRUE, унаследует дескриптор объекта.