Перехват строк со стороннего консольного приложения
Консольное приложение написано на Microsoft Visual C++, моё приложение будет представлять интерфейсную часть написанную на Borland C++ Builder.
Консольное приложение запускается с моего приложения.
Несколько дней уже сижу в гугле и нигде не нашёл толкового работающего примера.
Консольное приложение написано на Microsoft Visual C++, моё приложение будет представлять интерфейсную часть написанную на Borland C++ Builder.
Консольное приложение запускается с моего приложения.
Несколько дней уже сижу в гугле и нигде не нашёл толкового работающего примера.
Тебе сюда + в примерах Билдера есть готовый пример.
Это всё замечательно, я видел таких примеров кучу, но в них есть одна проблема. Они считывают весь вывод консоли, а мне нужна новая строка (как только строка появилась её нужно считать, если новой строки нет - ждём), и в этих примерах стоит ожидание завершения процесса, в моём случае консоль может завершить только пользователь, когда ему захочется, т.е. ожидание завершения процесса пользователем.
Так читайте все символы и реагируйте как-то только когда появится 0x0A.
Не совсем понял, что имеется в виду, но завершение процесса самим собой и завершение его пользователем - одно и тоже, ибо процесс завершается.
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, NULL, NULL, &start, &ProcessInfo);
if ( Res )
{
do
{
Apprunning = WaitForSingleObject(ProcessInfo.hProcess, 100);
Application->ProcessMessages();
do
{
Result = PeekNamedPipe(ReadPipe, NULL, 0, NULL, (LPDWORD) &DataSize, NULL);
if ((Result) && (DataSize))
{
if (DataSize > READ_BUFFER_SIZE) DataSize = READ_BUFFER_SIZE;
ReadFile(ReadPipe, Buffer, DataSize, &BytesRead, NULL);
Buffer[BytesRead] = 0;
OemToAnsi(Buffer, Buffer);
ListBox1->Items->Text = ListBox1->Items->Text + Buffer;
ListBox1->ItemIndex = ListBox1->Items->Count-1; // выделение текущей строки
}
}
while ((Result) && (DataSize));
}
while (Apprunning == WAIT_TIMEOUT);
}
Как сделать то, о чём вы говорите (если ReadFile считывает блоками)?
Я не работал с туннелями, но ReadFile() в обычном режиме может считывать и по одному байту. Читайте так, и когда попадётся 0x0A считайте, что вот она, ваша новая строка (0x0A == "\n").
Либо, и так будет быстрее/лучше, можно всё читать в буфер и потом сканировать его на предмет \n.
Вот что происходит с текущим кодом:
Вывод консоли:
Led = On
Led = Off
Led5 = 01101010
В буфер он записывает всё, получается Buffer = 'Led = On\n\rLed = Off\n\rLed5 = 01101010\n\r'
Или я чего-то не понимаю, или жалко тут нет смайлика *wall*... Чем вам не вариант пройтись по Buffer после прочтения-то?
if buffer = #10 then
ProcessNewLine( copy(buffer, PreviousLineBreak, i) );
Самый что ни на есть риалтайм.
Это по-моему как ехать в Москву, копая тоннель через Австралию. Зачем хакать систему, раз есть стандартные средства?
for i := 0 to length(buffer) - 1 do
if buffer = #10 then
ProcessNewLine( copy(buffer, PreviousLineBreak, i) );
попробую.
Попробовал читать по символам:
Чтобы выполнить ReadFile(ReadPipe, &Buffer[0], 1, &BytesRead, NULL) функция ReadFile требует завершения работы консоли иначе прога просто зависает на строчке с ReadFile.
Вот пример консольного приложения, в котором бесконечно идёт вывод строк (каждая появляется через 5 сек). Вот как тут отлавливать и обрабатывать их? (строки)