![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ловим сообщения программы [D7, XP]
cruiser © (2008-09-30 17:06:00)Здравствуйте уважаемые Мастера! Вопрос:
Как можно реализовать на Delphi отлов сообщений некоторой программы, которые она выдает в окно командной строки после её запуска из командной строки? Например, в окне cmd пишется: удаление произведено. А как мне отловить это сообщение и например поместить в showmessage моей программы?
Юрий Зотов (2008-09-30 23:38:00) [41]> cruiser © (30.09.08 23:12) [12]
> приложение приходит в ступор, а запущенное таким образом приложение
> ничего не делает.
Имеется в виду любое консольное или GUI приложение? С консольным все должно работать, а GUI ждет действий юзера. Наше приложение при этом тоже ждет - пока кто-то не запишет в stdout (а писать туда некому).
cruiser (2008-09-30 23:13:00) [42]т.е. и родитель и потомок (приложения) не работают в таком случае и приходится их убивать из диспетчера задач
cruiser (2008-09-30 23:12:00) [43]спасибо. попробую.
еще вопрос. при запуске любого приложения, вместо 'ping 127.0.0.1 -t' приложение приходит в ступор, а запущенное таким образом приложение ничего не делает . в чем ошибка?
Юрий Зотов (2008-09-30 23:07:00) [44]> cruiser © (30.09.08 22:35) [9]
> Убрал CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hThread);
Я бы их оставил, но CloseHandle(ProcessInfo.hThread) вызвал сразу после CreateProcess (на фига держать ненужный хэндл?), а CloseHandle(ProcessInfo.hProcess) - сразу после TerminateProcess (хотя тоже не уверен, что в этом есть смысл - но на всякий случай).
А вот TerminateThread - убрал бы. При прерывании процесса его поток прервется сам.
Riply (2008-09-30 23:06:00) [45]> [9] cruiser © (30.09.08 22:35)
> Спасибо большое. До этого я не догадался. Все было так просто.
> Убрал CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hThread); и всё заработало :)
А я бы их не убирала
cruiser (2008-09-30 22:35:00) [46]Спасибо большое. До этого я не догадался. Все было так просто. Убрал Clos
eHandle(ProcessInfo.hProcess);и всё заработало :)
CloseHandle(ProcessInfo.hThread);
Юрий Зотов (2008-09-30 22:22:00) [47]> cruiser © (30.09.08 21:47) [7]
Пара наводящих вопросов:
1. Какой смысл имеет хэндл процесса (или потока) ПОСЛЕ того, как ЭТОТ хэндл УЖЕ был закрыт?
2. Какой смысл имеет прерывание потока (TerminateThread) ПОСЛЕ того, как был прерван ВЕСЬ процесс ЭТОГО потока (TerminateProcess)?
cruiser (2008-09-30 21:47:00) [48]Извиняюсь...
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
FreeMem(Buffer);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
windows.TerminateProcess(ProcessInfo.hProcess,process_terminate);
windows.TerminateThread(ProcessInfo.hThread,1)
end;
Юрий Зотов (2008-09-30 21:43:00) [49]Куда добавили? Показывайте код. И WAIT_OBJECT_0 тут ни при чем.
cruiser (2008-09-30 21:14:00) [50]Спасибо!
Добавил этоwindows.TerminateProcess(ProcessInfo.hProcess,WAIT_OBJECT_0), но ничего не срабатывает. Процесс так и висит. STILL_ACTIVE этот тоже пробовал не подходит. Подскажите, что не так?
Юрий Зотов (2008-09-30 20:55:00) [51]TerminateProcess.
http://msdn.microsoft.com/en-us/library/ms686714(VS.85).aspx
cruiser (2008-09-30 20:50:00) [52]Спасибо за подсказку. Стал использовать вот такой код:
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
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);
end;
FreeMem(Buffer);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ReadPipe);
CloseHandle(WritePipe);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Clear;
RunDosInMemo('ping 127.0.0.1 -t', Memo1);
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
FreeMem(Buffer);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end;
end.
Возник вопрос:
Как сделать, что бы по нажатию на кнопку, например button2 или в процедуре FormCloseQuery выполнить принудительное завершение процесса, запущенного из программы? (в данном случае ping...)
Спасибо!
cruiser (2008-09-30 17:08:00) [53]Спасибо. Я просто не такую фразу вбивал в поисковике :)
Vlad Oshin (2008-09-30 17:07:00) [54]http://yandex.ru/yandsearch?rpt=rad&text=%D0%BF%D0%B5%D1%80%D0%B5%D1%85%D0%B2%D0%B0%D1%82%20%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4%D0%B0%20%D0%B2%20%D0%BA%D0%BE%D0%BD%D1%81%D0%BE%D0%BB%D1%8C%20delphi