Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Перехват строк со стороннего консольного приложения

57K
09 апреля 2010 года
BeatCheat
10 / / 09.04.2010
Создаю приложение, которое должно считывать данные из стороннего консольного приложения в реальном времени, т.е. как только появилась строка в консоли её тут же нужно считать в моё приложение, при чём в консоли идёт постоянный вывод данных, консольное приложение при запуске сворачивается. Должна быть возможность управлять компонентами моего приложения не дожидаясь завершения консольного приложения (сворачивать\разворачивать консоль, нажимать кнопки в моём приложении и т.д.).

Консольное приложение написано на Microsoft Visual C++, моё приложение будет представлять интерфейсную часть написанную на Borland C++ Builder.

Консольное приложение запускается с моего приложения.

Несколько дней уже сижу в гугле и нигде не нашёл толкового работающего примера.
246
10 апреля 2010 года
GIZMO
1.8K / / 30.07.2004
Цитата: BeatCheat
Создаю приложение, которое должно считывать данные из стороннего консольного приложения в реальном времени, т.е. как только появилась строка в консоли её тут же нужно считать в моё приложение, при чём в консоли идёт постоянный вывод данных, консольное приложение при запуске сворачивается. Должна быть возможность управлять компонентами моего приложения не дожидаясь завершения консольного приложения (сворачивать\разворачивать консоль, нажимать кнопки в моём приложении и т.д.).

Консольное приложение написано на Microsoft Visual C++, моё приложение будет представлять интерфейсную часть написанную на Borland C++ Builder.

Консольное приложение запускается с моего приложения.

Несколько дней уже сижу в гугле и нигде не нашёл толкового работающего примера.



Тебе сюда + в примерах Билдера есть готовый пример.

57K
18 апреля 2010 года
BeatCheat
10 / / 09.04.2010
Цитата: GIZMO
Тебе сюда + в примерах Билдера есть готовый пример.



Это всё замечательно, я видел таких примеров кучу, но в них есть одна проблема. Они считывают весь вывод консоли, а мне нужна новая строка (как только строка появилась её нужно считать, если новой строки нет - ждём), и в этих примерах стоит ожидание завершения процесса, в моём случае консоль может завершить только пользователь, когда ему захочется, т.е. ожидание завершения процесса пользователем.

253
19 апреля 2010 года
Proger_XP
1.5K / / 07.08.2004
Цитата: BeatCheat
Это всё замечательно, я видел таких примеров кучу, но в них есть одна проблема. Они считывают весь вывод консоли, а мне нужна новая строка (как только строка появилась её нужно считать, если новой строки нет - ждём)


Так читайте все символы и реагируйте как-то только когда появится 0x0A.

Цитата: BeatCheat
и в этих примерах стоит ожидание завершения процесса, в моём случае консоль может завершить только пользователь, когда ему захочется, т.е. ожидание завершения процесса пользователем.


Не совсем понял, что имеется в виду, но завершение процесса самим собой и завершение его пользователем - одно и тоже, ибо процесс завершается.

57K
19 апреля 2010 года
BeatCheat
10 / / 09.04.2010
Вот пример кода, где идёт считывание:
Код:
Res = CreateProcess(NULL, DosApp.c_str(), &Security , &Security , TRUE,
    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 считывает блоками)?
253
19 апреля 2010 года
Proger_XP
1.5K / / 07.08.2004

Я не работал с туннелями, но ReadFile() в обычном режиме может считывать и по одному байту. Читайте так, и когда попадётся 0x0A считайте, что вот она, ваша новая строка (0x0A == "\n").
Либо, и так будет быстрее/лучше, можно всё читать в буфер и потом сканировать его на предмет \n.
57K
19 апреля 2010 года
BeatCheat
10 / / 09.04.2010
сканировать всё и искать что-то мне не подходит. Мне нужно тут же обрабатывать новую строку. Например, вывелась в консоли цифра 8, я её считываю и прорисовываю её в интерфейсе. Т.е. нужно обрабатывать в реалтайме.

Вот что происходит с текущим кодом:

Вывод консоли:

Led = On
Led = Off
Led5 = 01101010

В буфер он записывает всё, получается Buffer = 'Led = On\n\rLed = Off\n\rLed5 = 01101010\n\r'
8.2K
19 апреля 2010 года
bagie2
299 / / 26.10.2008
Поставьте хук в чужом приложении на WriteConsoleA\WriteConsoleW или на ntdll!CsrClientCallServer тогда будет вам в реалтайме.
253
19 апреля 2010 года
Proger_XP
1.5K / / 07.08.2004
Цитата: BeatCheat
В буфер он записывает всё, получается Buffer = 'Led = On\n\rLed = Off\n\rLed5 = 01101010\n\r'


Или я чего-то не понимаю, или жалко тут нет смайлика *wall*... Чем вам не вариант пройтись по Buffer после прочтения-то?

 
Код:
for i := 0 to length(buffer) - 1 do
  if buffer = #10 then
    ProcessNewLine( copy(buffer, PreviousLineBreak, i) );

Самый что ни на есть риалтайм.
Цитата:
Поставьте хук в чужом приложении на WriteConsoleA\WriteConsoleW или на ntdll!CsrClientCallServer тогда будет вам в реалтайме.


Это по-моему как ехать в Москву, копая тоннель через Австралию. Зачем хакать систему, раз есть стандартные средства?

57K
19 апреля 2010 года
BeatCheat
10 / / 09.04.2010
Цитата:

for i := 0 to length(buffer) - 1 do
if buffer = #10 then
ProcessNewLine( copy(buffer, PreviousLineBreak, i) );


попробую.

57K
22 апреля 2010 года
BeatCheat
10 / / 09.04.2010
Что-то никак...

Попробовал читать по символам:
Чтобы выполнить ReadFile(ReadPipe, &Buffer[0], 1, &BytesRead, NULL) функция ReadFile требует завершения работы консоли иначе прога просто зависает на строчке с ReadFile.

Вот пример консольного приложения, в котором бесконечно идёт вывод строк (каждая появляется через 5 сек). Вот как тут отлавливать и обрабатывать их? (строки)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог