Получение вывода из процесса [решено]

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Получение вывода из процесса [решено]

Сообщение alaken » 06.04.2010 12:23:15

руководствуясь мануалом решил испробовать TProcess, столкнулся с проблемой, вывод представляется немного не в том виде если я его читаю пока работает запущенный процесс.
вот код:
Код: Выделить всё
var
    n
   ,idx
   ,Count
   : Integer;

   szBuffer: String; 
   AProcess: TProcess;
   AStringList: TStringList;
   AMemoryStream: TMemoryStream;
   BytesRead: LongInt; 

const
  READ_BYTES = 2048;

begin

   AProcess := TProcess.Create(nil);   
   AProcess.CommandLine := 'ping 101.140.12.151 -n 4 -l 1024'
   AProcess.Options := AProcess.Options + [poUsePipes, poNoConsole];
   AProcess.Execute;

   AStringList := TStringList.Create;
   AMemoryStream := TMemoryStream.Create;

   ListBox1.Clear;
   Memo1.Clear;
   BytesRead := 0;
   szBuffer := '';
   while AProcess.Running do
   begin
     AMemoryStream.SetSize(BytesRead + READ_BYTES);
     n := AProcess.Output.Read((AMemoryStream.Memory + BytesRead)^, READ_BYTES);

     if
       n > 0
     then
     begin

       Inc(BytesRead, n);
       AMemoryStream.SetSize(BytesRead);
       AStringList.LoadFromStream(AMemoryStream);
       szBuffer := szBuffer + AStringList.Text;
       Memo1.Text := Cp866ToUtf8(szBuffer);

     end
     else
     begin
       Sleep(100);
     end;
   end;

   AStringList.Free;
   AMemoryStream.Clear;
   AMemoryStream.Free; 
   AProcess.Free;


после выполнения Memo1.Text содержит следующий текст

Ответ №1

Обмен пакетами с 101.140.12.151 по 1024 байт:



Ответ от 101.140.12.151:
число байт=1024 время=3мс TTL=128

Ответ от 101.140.12.151:
число байт=1024 время=3мс TTL=128

Ответ от 101.140.12.151:
число байт=1024 время=2мс TTL=128

Ответ от 101.140.12.151:
число байт=1024 время=3мс TTL=128



Статистика Ping для 101.140.12.151:

Пакетов: отправлено = 4, получено = 4, потеряно = 0 (0% потерь),

Приблизительное время приема-передачи в мс:

Минимальное = 2мсек, Максимальное = 3 мсек, Среднее = 2 мсек



но если взять из буфера после выполнения процесса
Код: Выделить всё
   AMemoryStream.Seek(0, 0);
   AStringList.LoadFromStream(AMemoryStream);
   Memo1.Text := CP866ToUTF8(AStringList.Text); 

то результат будет
Ответ №2

Обмен пакетами с 101.140.12.151 по 1024 байт:



Ответ от 101.140.12.151: число байт=1024 время=2мс TTL=128

Ответ от 101.140.12.151: число байт=1024 время=3мс TTL=128

Ответ от 101.140.12.151: число байт=1024 время=3мс TTL=128

Ответ от 101.140.12.151: число байт=1024 время=3мс TTL=128



Статистика Ping для 101.140.12.151:

Пакетов: отправлено = 4, получено = 4, потеряно = 0 (0% потерь),

Приблизительное время приема-передачи в мс:

Минимальное = 2мсек, Максимальное = 3 мсек, Среднее = 2 мсек

             ╚╨╘     ААА @@@                                     ╚╨╘     ААА ╚╨╘ ╚╨╘ ╚╨╘ ╚╨╘ ╚╨╘ ╚╨╘ ╚╨╘ ╚╨╘ ╚╨╘ ╚╨╘ ╚╨╘                                                         ░


как правильно получать ответ от работающего процесса?
Последний раз редактировалось alaken 14.04.2010 15:44:49, всего редактировалось 1 раз.
alaken
постоялец
 
Сообщения: 221
Зарегистрирован: 18.02.2010 09:02:13

Re: Получение вывода из процесса

Сообщение coyot.rush » 06.04.2010 17:42:37

Ось какая? Судя по всему винда . :?: если так то через пайпы. Ищите в DRKB (Delphi Russian Knowlege Base)
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48

Re: Получение вывода из процесса

Сообщение Mr.Smart » 06.04.2010 17:44:54

coyot.rush
TProcess какраз и использует анонимные каналы (Anonym Pipes).
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: Получение вывода из процесса

Сообщение coyot.rush » 06.04.2010 17:59:49

TProcess какраз и использует анонимные каналы (Anonym Pipes).


Не знаю не использую эт класс, имхо под Linux эт класс в состояние альфа :x

Лучше посмотреть исходики DC. Там ошибок меньше :D
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48

Re: Получение вывода из процесса

Сообщение alaken » 07.04.2010 13:48:25

сам нашел как правильно делать, по крайней мере результат правильный программа выдает,
привожу код 100% работает, вдруг кому нибудь понадобится.
а мануал однозначно править...
Код: Выделить всё
...
var
   n: Integer;

   AProcess: TProcess;
   AStringList: TStringList;
   AMemoryStream: TMemoryStream;
   BytesRead: LongInt; 

begin

   AProcess := TProcess.Create(nil);   
   AProcess.CommandLine := 'ping 101.140.12.151 -n 4 -l 1024'
   AProcess.Options := AProcess.Options + [poUsePipes, poNoConsole];
   AProcess.Execute;

   AStringList := TStringList.Create;
   AMemoryStream := TMemoryStream.Create;

   ListBox1.Clear;
   Memo1.Clear;
   BytesRead := 0;
   szBuffer := '';
   while AProcess.Running do
   begin
     AMemoryStream.SetSize(BytesRead + AProcess.Output.NumBytesAvailable);
     n := AProcess.Output.Read((AMemoryStream.Memory + BytesRead)^, AProcess.Output.NumBytesAvailable);

     if
       n > 0
     then
     begin

       Inc(BytesRead, n);
       AMemoryStream.SetSize(BytesRead);
       AStringList.LoadFromStream(AMemoryStream);
       Memo1.Text := Memo1.Text + Cp866ToUtf8(AStringList.Text);

     end
     else
     begin
       Sleep(100);
     end;
   end;

   n := 0;

   if
     AProcess.Output.NumBytesAvailable > 0
   then
     n := AProcess.Output.Read((AMemoryStream.Memory + BytesRead)^, AProcess.Output.NumBytesAvailable);

   if
     n > 0
   then
   begin
     Inc(BytesRead, n);
     AMemoryStream.SetSize(BytesRead);
     AStringList.LoadFromStream(AMemoryStream);
     Memo1.Text := Memo1.Text + Cp866ToUtf8(AStringList.Text);
     Memo1.SelStart := Length(Memo1.Text) - 1;
   end;

   AStringList.Free;
   AMemoryStream.Clear;
   AMemoryStream.Free; 
   AProcess.Free;
end;
alaken
постоялец
 
Сообщения: 221
Зарегистрирован: 18.02.2010 09:02:13

Re: Получение вывода из процесса [решено]

Сообщение Linus » 31.12.2016 20:16:38

Из всего выше написанного не очень то ясно как сделать так:

запускаем "evtest /dev/input/event9 | grep ', code' "
висим пока не появится хотя бы одна запись в выводе
убиваем процесс и получаем заветную строчку.

Если висеть так
Код: Выделить всё
proc.output.size=0
то получим Cannot seek on pipe
если так:
Код: Выделить всё
...
while proc.Running do
   begin
      if proc.Output.NumBytesAvailable>0 then   break;     
   end;

    proc.Active:=false;
    setlength(bufer, proc.Output.NumBytesAvailable);
    proc.Output.Read(bufer[0],proc.Output.NumBytesAvailable);
    key_setup.Caption:=string(bufer); \0
...

то получим
Код: Выделить всё
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x810 product 0x3 version 0x110
Input device name: "USB Controller"
бла бла бла

т.е. хлам
Linus
новенький
 
Сообщения: 47
Зарегистрирован: 11.01.2013 22:01:28

Re: Получение вывода из процесса [решено]

Сообщение olegy123 » 01.01.2017 01:00:43

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

Код: Выделить всё
#define _debug_thread_print(x...) \
                flockfile(stdout); \
                printf(x);  \
                funlockfile(stdout); \
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: Получение вывода из процесса [решено]

Сообщение Linus » 01.01.2017 17:10:30

Всем спасибо, разобрался.

Код: Выделить всё
var
  Proc:TProcess;
  n,subpos:LongInt;
  str:array of byte;
begin
   proc:=TProcess.Create(nil);
   proc.Options:=[poUsePipes, poNoConsole];
   proc.CommandLine:='evtest '+dev;
   Proc.Execute;

   while proc.Running do
   begin
     setlength(str,proc.Output.NumBytesAvailable);
     n:=proc.Output.Read(str[0],proc.Output.NumBytesAvailable);

     if (n>0) then
     begin
       subpos:=pos(', value',string(str));
       if (subpos>0) then
       begin
         delete(string(str),1,subpos+7); //-value
         subpos:=pos(#10,string(str));
         if subpos=0 then subpos:=length(string(str));

         string(str):=copy(string(str),1,subpos);
         proc.Terminate(0);
       end;
     end
     else
        Sleep(100);
   end;
   proc.Free;
   ...
Linus
новенький
 
Сообщения: 47
Зарегистрирован: 11.01.2013 22:01:28


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 13

Рейтинг@Mail.ru