Форум по программированию Delphi Sources

 



Вернуться   Форум по программированию Delphi Sources > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 19.05.2019, 16:40
AndyBogart AndyBogart вне форума
Прохожий
 
Регистрация: 19.05.2019
Сообщения: 4
Версия Delphi: Delphi 7
Репутация: 10
Вопрос Отследить, что программа зависла

Здравствуйте.

Пытаюсь написать приложение, которое должно отследить, что определённая программа зависла и принудительно её перезапустить. То есть завершить процесс и запустить заново. Ну, и заодно записать это действие в лог и/или сообщить мне на почту.

Собственно проблема заключается только в том, чтобы корректно отследить, что процесс завис. Как мне это сделать? Какой функцией?

Есть ли какие-то виды зависания программы? Выполнение/ожидание, зависла намертво.

Последний раз редактировалось AndyBogart, 19.05.2019 в 16:44.
Ответить с цитированием
  #2  
Старый 19.05.2019, 18:20
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 7,381
Версия Delphi: 7, XE3, 10.2
Репутация: 49088
По умолчанию

Ну, вообще понятие, что программа "зависла" нет.
То, что мы называем зависла, это просто значит, что она выполняет какие-то действия. Самый частый случай - программа по каким-то причинам вошла в бесконечный цикл. При этом, если цикл написан корректно (с учетом, что он может исполняться долго), то внешне это не выглядит, что программа "висит".
Винда определяет "висение" программы по тому, что она не отвечает на сообщения, что совершенно на самом деле не значит, что она висит, просто может выполняться какая-то длительная операция. Например, срвременные браузеры на старых (читай относительно медленных) компутерах в какой-то момент при загрузке могут отражаться как зависшие (Не отвечает или Not responding в заголовке окна).

Т.е. по твоему вопросу - надо делать примерно так же.
Если программа, которую ты мониторишь, твоя, то сделай в ней обработку какого-нибудь твоего сообщения. Монитор посылает его, если в течении какого-то времени/итераций это сообщение не обрабатывается, то убивай процесс.
Если программа не твоя, то пробуй посылать какое-нить из стандартных сообщений, которое точно должно обрабатываться, например, WM_PAINT.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
AndyBogart (20.05.2019)
  #3  
Старый 20.05.2019, 03:57
AndyBogart AndyBogart вне форума
Прохожий
 
Регистрация: 19.05.2019
Сообщения: 4
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

lmikle, да программа не моя.
Для меня будет достаточно определить, что программа зависла, если она не отвечает допустим 10-20 секунд. Независимо от того работает там что-то в фоне или нет.
А как мне перехватить WM_PAINT с другого приложения?
Ответить с цитированием
  #4  
Старый 20.05.2019, 12:21
Аватар для Vayrus
Vayrus Vayrus вне форума
Исполняемый Ретровирус
 
Регистрация: 09.08.2008
Адрес: Umbrella Corporation
Сообщения: 742
Репутация: 1293
По умолчанию

Учимся пользоваться гуглом и тп, вот пример с SendMessageTimeout:

Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  H : THandle;
  lngReturnValue : longint;
  DWResult : DWORD;
begin
  H := FindWindow('Notepad', nil);
  if H > 0 then
  begin
    lngReturnValue := SendMessageTimeout(
      H, WM_NULL, 0, 0, SMTO_ABORTIFHUNG And SMTO_BLOCK,
      1000, DWResult
    );
    if lngReturnValue > 0 then
      ShowMessage('Responding')
    else
      ShowMessage('Not responding');
  end
  else
    ShowMessage('Application not found');
end;

Вот здесь же пример на сайте с использованием IsHungAppWindow:
http://www.delphisources.ru/pages/fa...response2.html

Проверку по таймеру прикрутить уже сможешь сам

Последний раз редактировалось Vayrus, 20.05.2019 в 12:24.
Ответить с цитированием
Этот пользователь сказал Спасибо Vayrus за это полезное сообщение:
AndyBogart (22.05.2019)
  #5  
Старый 22.05.2019, 06:09
AndyBogart AndyBogart вне форума
Прохожий
 
Регистрация: 19.05.2019
Сообщения: 4
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Благодарю, Лорд Вайрус )
Ответить с цитированием
  #6  
Старый 05.06.2019, 02:29
IvoX IvoX вне форума
Прохожий
 
Регистрация: 12.04.2019
Сообщения: 12
Версия Delphi: D7, Delphi 10.2
Репутация: 10
По умолчанию

В виртуалке часто определяет работающее приложение как зависшее
если пользую этот код:
Код:
function AppIsResponding(ClassName: string): Boolean;
const
  { Specifies the duration, in milliseconds, of the time-out period }
  TIMEOUT = 200;
var
  Res: DWORD;
  h: HWND;
begin
  h := FindWindow(PChar(ClassName), nil);
  if h <> 0 then
    Result := SendMessageTimeOut(H,
      WM_NULL,
      0,
      0,
      SMTO_NORMAL or SMTO_ABORTIFHUNG,
      TIMEOUT,
      Res) <> 0
  else
    ShowMessage(Format('%s not found!', [ClassName]));
end;

в примере вообще 50 мс было

Последний раз редактировалось IvoX, 05.06.2019 в 02:32.
Ответить с цитированием
Ответ



Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 15:54.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources", 2004-2019

ВКонтакте   Facebook   Twitter