|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
30.05.2008, 12:58 | #1 |
Регистрация: 30.05.2008
Сообщений: 5
|
Console Output Redirection, PeekNamedPipe
Добрый день.
Сделал сабж, всё работает за исключением одного большого "НО". Бьюсь над этим "НО" уже достаточно долгое время, никак не найду решения. Итак, стандартная задача: перехват вывода консольной программы. Решение тоже стандартное: создаются read/write pipes с помощью CreatePipe(), затем вызывается CreateProcess(), которому в STARTUPINFO передаются handles этих pipes. Чтение из pipe делается примерно так: Код:
А теперь - то самое "НО", о котором я упоминал. Если дочерний процесс (который вызывается с помощью CreateProcess) выполняет много действий или использует что-то вроде Sleep(50) между выводами в консоль, то PeekNamedPipe() в моей программе очень часто возвращает 0 независимо от того, вывел дочерний процесс что-то в консоль или нет. Из-за этого чтение из m_hStdOutReadPipe происходит не каждый раз, как дочерний процесс что-то выводит в консоль, а во много раз реже. Чтобы не быть голосовным, пусть у нас есть такая консольная программа, вывод которой мы хотим перехватить: Код:
Line 0 Line 1 Line 2 ... А при попытке перехватить вывод этой программы с помощью pipe сначала мы вообще ничего не видим, а в самом конце нам разом вываливаются все строки от Line 0 до Line 99 Я уже изрыл весь MSDN по поводу этого вопроса, пробовал различные реализации перехвата консольного вывода - с тем же результатом. Ничего так и не смог найти. Может быть, кто-то уже сталкивался с подобной проблемой и знает, что можно сделать? Люди, поделитесь! Или хоть ссылочку дайте, где искать. Последний раз редактировалось B_N; 30.05.2008 в 16:45. |
30.05.2008, 16:47 | #2 |
Новичок
Джуниор
Регистрация: 18.01.2008
Сообщений: 1,720
|
Через OVERLAPPED попробуйте читать.
|
30.05.2008, 19:10 | #3 |
Регистрация: 30.05.2008
Сообщений: 5
|
|
31.05.2008, 01:18 | #4 | ||
Новичок
Джуниор
Регистрация: 18.01.2008
Сообщений: 1,720
|
Цитата:
Цитата:
|
||
02.06.2008, 17:59 | #5 |
Участник клуба
Регистрация: 08.10.2007
Сообщений: 1,185
|
Я потестил это в Delphi и вот к чему пришёл: проблема в том, что при использовании Write (printf) в консоль выводится всё потоком, но при появлении пайпа (похоже, что и в Delphi, и в C++) откуда-то появляется буферизация. Если вместо Write (printf) использовать WriteFile, то всё выводится без задержек, потоком.
Во вложении исходники: Reader - читает вывод запущенного им процесса, Writer - пишет строки с помощью Write, Writer2 - пишет строки с помощью WriteFile. |
03.06.2008, 22:45 | #6 |
Регистрация: 30.05.2008
Сообщений: 5
|
По-моему, операции вывода в принципе являются буферизированными, причем буферизация эта управляется самой системой. Поэтому и существуют функции типа flush, fflush, заставляющие весь этот буфер слиться в место назначения.
Но это со стороны дочернего процесса, вывод которого мы хотим перехватить. В данном случае вопрос в том, как прочесть из нашей программы, которая запускает дочерний процесс, данные этого дочернего процесса, которые он вроде бы вывел, но которые еще не попали в pipe. С overlapped пока что не получилось, но похоже, что это единственный возможный вариант решения. Или начать пляску с бубном вокруг размера памяти для pipe - вдруг какое-то "магическое" значение решит проблему с буферизацией... |
04.06.2008, 15:10 | #7 | |
Участник клуба
Регистрация: 08.10.2007
Сообщений: 1,185
|
Цитата:
Не думаю, что со стороны, читающей через пайп, можно что-то ещё сделать; наверное, это всё. Остаётся только по возможности использовать в дочернем процессе (если своя прога) апишные функции. |
|
05.09.2021, 13:57 | #8 | |
Регистрация: 22.08.2018
Сообщений: 8
|
Цитата:
Проблема легко решается либо остановкой дочернего процесса, либо закрытием "ручки pipe". Но мне это не подходит, поскольку дочерний процесс зациклен и выводит данные постепенно (порциями), котрые и считывать нужно родительским процессом порциями, по мере поступления. Это в принципе возможно? Пока конець pipe не закрыт ReadFile "висит", а PeekNamedPipe (которым пробовал заменить ReadFile) тоже ничего не читает без окончания процесса или закрытия pipe. |
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Вопрос по ввыводу данных в output.txt C++ | Jugger | Общие вопросы C/C++ | 2 | 31.01.2008 16:14 |
Открытие документов Microsofrt Common Console через delphi | )Игнат( | Общие вопросы Delphi | 6 | 24.01.2008 17:09 |
Выполнение хранимой процедуры с output параметром | Иванчо | БД в Delphi | 5 | 26.10.2007 14:59 |