Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Ловим сообщения программы [D7, XP]


Страницы:   1 2 3

cruiser ©   (2008-09-30 17:06:00) 

Здравствуйте уважаемые Мастера! Вопрос:
Как можно реализовать на Delphi отлов сообщений некоторой программы, которые она выдает в окно командной строки после её запуска из командной строки? Например, в окне cmd пишется: удаление произведено. А как мне отловить это сообщение и например поместить в showmessage моей программы?


cruiser   (2008-10-01 13:48:00) [21]

А как же тогда будет верно остановить его (дочернего процесса) работу и выкинуть из памяти, если это очень нужно?


Сергей М.   (2008-10-01 13:42:00) [22]


> в любой момент прибивался бы дочерний процесс


Это, мягко говоря, не есть гуд.
Если процесс жив и нормально реагирует на ожидаемые события ввода, "прибивать" его не только нехорошо, но и в отдельных случаях чревато опасными последствиями.


cruiser   (2008-10-01 13:37:00) [23]

Реализовал уже :) Я просто отвечал вот на это:

> завершение
> > приложения ведет к автоматическому уничтожению порожденного
>
> > процесса cmd.exe, если на этот момент он еще активен.

а closequery, так, попало в цитату :) Сегодня вечером проверю предложенный Вами код.


Сергей М.   (2008-10-01 13:30:00) [24]


> мне нужно что бы моё приложение не закрывалось, а по нажатию
> на кнопку стоп в любой момент прибивался бы дочерний процесс


И что тебе мешает реализовать такую логику ?


cruiser   (2008-10-01 12:41:00) [25]

Спасибо. Дома попробую этот код.

> Никаких обработчиков OnCloseQuery не требуется - завершение
> приложения ведет к автоматическому уничтожению порожденного
> процесса cmd.exe, если на этот момент он еще активен.

А мне нужно что бы моё приложение не закрывалось, а по нажатию на кнопку стоп в любой момент прибивался бы дочерний процесс.


Сергей М.   (2008-10-01 10:08:00) [26]


> окно консоли видно, но в нём ничего не пишется


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

Вот этот чуть подкорректированный код чудесно работает и в точности выполняет поставленную тобой задачу:


var
Security: TSecurityAttributes;
ReadPipe, WritePipe: THandle;
Start: TStartupInfo;
ProcessInfo: TProcessInformation;
Buffer: PChar;
Apprunning: Cardinal;
BytesRead: Cardinal;

procedure RunDosInMemo(CmdLine: string; AMemo: TMemo);
const
ReadBuffer = 2400;
begin

with Security do
begin
  nlength := SizeOf(TSecurityAttributes);
  binherithandle := true;
  lpsecuritydescriptor := nil;
end;
if Createpipe(ReadPipe, WritePipe,
  @Security, 0) then
begin
  Buffer := AllocMem(ReadBuffer + 1);
  FillChar(Start, Sizeof(Start), #0);
  start.cb := SizeOf(start);
  start.hStdOutput := WritePipe;
  start.hStdInput := ReadPipe;
  start.dwFlags := STARTF_USESTDHANDLES +
    STARTF_USESHOWWINDOW;
  start.wShowWindow := SW_HIDE;

  if CreateProcess(nil,
    PChar(CmdLine),
    @Security,
    @Security,
    true,
    NORMAL_PRIORITY_CLASS,
    nil,
    nil,
    start,
    ProcessInfo) then
  begin
    CloseHandle(ProcessInfo.hThread);
    while not Application.Terminated do begin
      Apprunning := WaitForSingleObject
        (ProcessInfo.hProcess, 10);
      if Apprunning <> WAIT_TIMEOUT then Break;
      ReadFile(ReadPipe, Buffer[0],
        ReadBuffer, BytesRead, nil);
      Buffer[BytesRead] := #0;
      OemToAnsi(Buffer, Buffer);
      AMemo.Text := AMemo.text + string(Buffer);
      Application.ProcessMessages;
    end;
  end;
  FreeMem(Buffer);
  if Apprunning = WAIT_TIMEOUT then TerminateProcess(ProcessInfo.hProcess, 0);
  CloseHandle(ProcessInfo.hProcess);
  CloseHandle(ReadPipe);
  CloseHandle(WritePipe);
end;

end;

procedure TForm1.Button3Click(Sender: TObject);
begin
RunDosInMemo('ping 127.0.0.1 -t', Memo);
end;


Никаких обработчиков OnCloseQuery не требуется - завершение приложения ведет к автоматическому уничтожению порожденного процесса cmd.exe, если на этот момент он еще активен.


cruiser   (2008-10-01 09:42:00) [27]

В листинге наверху видно что, например,  'ping 127.0.0.1 -t'
Заметил еще вот что. При запуске дочернего процесса с параметром sw_hide, то она не отрабатывает свою функциональность. А вот если с параметром sw_normal, то окно консоли видно, но в нём ничего не пишется (я так понимаю и должно быть). Но при этом код не отрабатывает запись в memo1.
Пробовал вот сюда:
repeat
      Apprunning := WaitForSingleObject
        (ProcessInfo.hProcess, 10);
      ReadFile(ReadPipe, Buffer[0],
        ReadBuffer, BytesRead, nil);
      Buffer[BytesRead] := #0;
      OemToAnsi(Buffer, Buffer);
      AMemo.Text := AMemo.text + string(Buffer);

      Application.ProcessMessages;
    until (Apprunning <> WAIT_TIMEOUT);

вместо AMemo.Text := AMemo.text + string(Buffer) ставить showmessage string(buffer) и думал что сообщение будет выдаваться при каждом новом выводи консольной программы. А ннееет - выдается только в конце по завршению процесса консольной проги и несколько раз, пока всё не покажет... Странно как-то. Сегодня буду пробовать другой код, найденный на просторах инета...


Сергей М.   (2008-10-01 09:06:00) [28]


> cruiser ©   (01.10.08 00:57) [26]


Чему у тебя равен параметр CmdLine при вызове процедуры ?


cruiser   (2008-10-01 00:57:00) [29]

Опытным путем определил что висяку способствует параметр start.dwFlags. Если его закоментить, то дочерняя прога запускается и отрабатывает, правда наша программа не видит момента закрытия консольного приложения и тупо висит. +  в этом случае так же не идет перехват того, что программа выдает в консоль.


Германн   (2008-10-01 00:54:00) [30]


> Подскажите, на что обратить внимание?

Нет это я ошибся в арифметике. :(


cruiser   (2008-10-01 00:44:00) [31]

Подскажите, на что обратить внимание? Где очепяток?


Германн   (2008-10-01 00:33:00) [32]


>    if CreateProcess(nil,
>      PChar(CmdLine),
>      @Security,
>      @Security,
>      true,
>      NORMAL_PRIORITY_CLASS,
>      nil,
>      nil,
>      start,
>      ProcessInfo) then
>

Тут нет очепяток?


cruiser   (2008-10-01 00:17:00) [33]


> Естесственно. Ключик -t это "Отправка пакетов на указанный
> узел до команды прерывания. Для вывода статистики и продолжения
> нажмите <Ctrl>+<Break>, для прекращения - <Ctrl>+<C>."

Это то здесь причем?


> Запустите ее под DOSом. Если не обругается - то это DOS-
> программа.

Не знаю что и делать. Запускаемая программа ругается в лог файле на неправильную  конфигурацию программы. Странно. Может какая-то защита стоит или недоработка, что программу нельзя запускать как дочерний процесс?


turbouser   (2008-10-01 00:12:00) [34]


> cruiser ©   (30.09.08 23:12) [12]
>
> спасибо. попробую.
> еще вопрос. при запуске любого приложения, вместо 'ping
> 127.0.0.1 -t' приложение приходит в ступор

Естесственно. Ключик -t это "Отправка пакетов на указанный узел до команды прерывания. Для вывода статистики и продолжения нажмите <Ctrl>+<Break>, для прекращения - <Ctrl>+<C>."


cruiser   (2008-10-01 00:01:00) [35]

Написано в описании проги: this program cannot be run in dos mode


Юрий Зотов   (2008-09-30 23:57:00) [36]

> cruiser ©   (30.09.08 23:55) [18]

Запустите ее под DOSом. Если не обругается - то это DOS-программа.


cruiser   (2008-09-30 23:55:00) [37]

Это exe файл, который при запуске с опр. параметрами пишет отчет совей работы в окно консоли. Может в это проблема?


Юрий Зотов   (2008-09-30 23:51:00) [38]

Обратил внимание на название процедуры - там есть слово DOS. Если это DOS-программа (а не консольная Windows-программа), то она может выводить не в stdout,  а напрямую в видеобуфер ($B800).


cruiser   (2008-09-30 23:45:00) [39]

есть предположение, что консольная прога выводит свои данные в окно консоли каким-то другим способом, отличным от того что мы пытаемся перехватить...


cruiser   (2008-09-30 23:41:00) [40]

В том то и дело что консольное. Т.е. это самое консольное приложение не просит никаких нажатий, а просто делает свою работу :( Куда копать?


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо