2014-09-01 4 views
-1

я могу использовать STARTF_USESTDHANDLES флаг в STARTUPINFO структуры для перенаправления stdin, stdout, stderr процесса, созданного CreateProcess.Перенаправление STDIN только и падение данные на стандартный вывод и стандартный поток ошибок

Documentation говорит для этого случая (STARTF_USESTDHANDLES флаг настоящего):

Члены hStdInput, hStdOutput и hStdError содержат дополнительную информацию . Если этот флаг указан при вызове одной из функций создания процесса , дескрипторы должны быть наследуемыми, а параметр функции bInheritHandles должен быть установлен в TRUE. Для получения дополнительной информации, см. Наследование ручек.

Но сама этих членов (hStdInput и т.д.) тот же документ говорит (например - hStdError):

Если dwFlags указывает STARTF_USESTDHANDLES, этот элемент является стандартная ручка ошибка процесса. В противном случае этот элемент игнорируется, а стандартным значением по умолчанию является буфер буфера консоли.

Если бы я подключить трубку к ребенку процесс стандартный вывод и не считывать данные из него, его переполнения буфера и в соответствии с this doc, ребенок prcess будет висеть через некоторое время при попытке записать данные на стандартный вывод, потому что

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

Могу ли я безопасно передать NULL для hStdOutput и hStdError членов STARTUPINFO структуры, когда STARTF_USESTDHANDLES флаг присутствует, чтобы избежать такой ситуации? Или я должен сделать поток опроса для очистки данных от трубы, чтобы перегрузить его буфер?

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

ответ

1

Откройте устройство NUL и используйте его как ручки hStdOutput и hStrError. Любые данные, записанные на устройство NUL, будут игнорироваться без возникновения ошибок. Это предпочтительнее, чем отсутствие дескриптора, так как отказ записи от стандартного вывода или стандартная ошибка в дочерних процессах может привести к преждевременному выходу из него. Обязательно сделайте дескриптор наследуемым, как указано в документации.

Что-то вроде:

SECURITY_ATTRIBUTES secattr; 
secattr.nLength = sizeof secattr; 
secattr.lpSecurityDescriptor = NULL; 
secattr.bInheritHandle = TRUE; 
hnul = CreateFile("NUL", GENERIC_WRITE, 0, &secattr, OPEN_EXISTING, 0, NULL); 
startupinfo.hStdOutput = hnul; 
startupinfo.hStdError = hnul; 

Я не уверен, если NUL устройство официально документированы Microsoft в любом месте. Однако это была часть Windows с тех пор, как появилась Windows. MS-DOS 1.0 поддерживал его. Он работает как Unix /dev/null, если вы знакомы с этим.

+0

Awesome, не знал, что в Windows существует аналог to/dev/null –

Смежные вопросы