![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Редирект консольного вывода
бывший © (2005-07-18 22:22:00)Есть клиент-серверное приложение. сервер сделан в виде консоли. необходим редирект вывода информации из консоли в мое приложение в "реальном масштабе времени" ) понимаю что необходим отдельный поток в котором я и буду совершать действо.
Пробовал создавать пайп и переадресовывать вывод при запуске консоли (createprocess) на этот пайп, постепенно читая из него. во-первых - передается не все, во-вторых в определенный момент консоль виснит. Подобные решения видел на www.sources.ru, к примеру.
В общем, мне нужна именно постепенная передача всего текста, отображаемого в консоле в мое приложение по мере его появления.
Я так понял выхода два - переадресация вывода (к примеру через пайп) - с этим вариантом по непонятным мне причинам облом вышел, чтение из некоего буфера консоли. Мастера, помогите!
Если необходимо привести те коды, что пробовал использовать, приведу. Пока для экономии места оставляю вопрос в таком виде.
бывший (2005-07-19 08:34:00) [61]наверняка у многих мастеров есть свои секреты работы с чужой консолью. поделитесь, плиз )
бывший (2005-07-19 08:30:00) [62]
function GetDosOutput(const CommandLine:string): string;
var
SA: TSecurityAttributes;
SI: TStartupInfo;
PI: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
WasOK: Boolean;
Buffer: array[0..255] of Char;
BytesRead: Cardinal;
WorkDir, Line: String;
begin
Application.ProcessMessages;
with SA do
begin
nLength := SizeOf(SA);
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
// создаём пайп для перенаправления стандартного вывода
CreatePipe(StdOutPipeRead, // дескриптор чтения
StdOutPipeWrite, // дескриптор записи
@SA, // аттрибуты безопасности
0 // количество байт принятых для пайпа - 0 по умолчанию
);
try
// Создаём дочерний процесс, используя StdOutPipeWrite в качестве стандартного вывода,
// а так же проверяем, чтобы он не показывался на экране.
with SI do
begin
FillChar(SI, SizeOf(SI), 0);
cb := SizeOf(SI);
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow := SW_SHOW; //SW_HIDE
hStdInput := GetStdHandle(STD_INPUT_HANDLE); // стандартный ввод не перенаправляем
hStdOutput := StdOutPipeWrite;
hStdError := StdOutPipeWrite;
end;
// Запускаем компилятор из командной строки
WorkDir := ExtractFilePath(CommandLine);
WasOK := CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil, PChar(WorkDir), SI, PI);
// Теперь, когда дескриптор получен, для безопасности закрываем запись.
// Нам не нужно, чтобы произошло случайное чтение или запись.
CloseHandle(StdOutPipeWrite);
// если процесс может быть создан, то дескриптор, это его вывод
if not WasOK then
raise Exception.Create('Could not execute command line!')
else
try
// получаем весь вывод до тех пор, пока DOS-приложение не будет завершено
Line := '';
repeat
// читаем блок символов (могут содержать возвраты каретки и переводы строки)
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
// есть ли что-нибудь ещё для чтения?
if BytesRead > 0 then
begin
// завершаем буфер PChar-ом
Buffer[BytesRead] := #0;
// добавляем буфер в общий вывод
Line := Line + Buffer;
end;
uMain.MainForm.richLog.Lines.Add(Line);
until not WasOK or (BytesRead = 0);
// ждём, пока завершится консольное приложение
WaitForSingleObject(PI.hProcess, INFINITE);
finally
// Закрываем все оставшиеся дескрипторы
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end;
finally
result:=Line;
CloseHandle(StdOutPipeRead);
end;
end;
сделано на пайпах. как такового "реал-тайма" нету. мне главное было проверить весь ли текст с консоли будет редиректнут. не весь ( пробовал и много других вариантов, в том числе и предложенный товарищем P.N.P.
Гаврила (2005-07-18 23:43:00) [63]
> Если необходимо привести те коды, что пробовал использовать,
> приведу
Видимо, пора
бывший (2005-07-18 22:55:00) [64]спасибо. интересное решение. оно работает, но все равно получает из консоли далеко не весь текст. консоль все время пополняется информацией (идет лог соединений клиентов, обмена данными, ошибок и т.д.) - этим вариантом получаю только 40% лога инициализации сервера и наступает тишина (не из-за таймаута точно).
этож каким макаром надо в этой консоле писать, чтобы редирект вывода не помогал? )
Мастера, жду вашей помощи и совета.
P.N.P. (2005-07-18 22:33:00) [65]Посмотри http://www.renderman.ru/forum/download.php/1,336,24/FoxUtils.txt
Оно?