|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Отследить, что программа зависла
Здравствуйте.
Пытаюсь написать приложение, которое должно отследить, что определённая программа зависла и принудительно её перезапустить. То есть завершить процесс и запустить заново. Ну, и заодно записать это действие в лог и/или сообщить мне на почту. Собственно проблема заключается только в том, чтобы корректно отследить, что процесс завис. Как мне это сделать? Какой функцией? Есть ли какие-то виды зависания программы? Выполнение/ожидание, зависла намертво. Последний раз редактировалось AndyBogart, 19.05.2019 в 16:44. |
#2
|
|||
|
|||
Ну, вообще понятие, что программа "зависла" нет.
То, что мы называем зависла, это просто значит, что она выполняет какие-то действия. Самый частый случай - программа по каким-то причинам вошла в бесконечный цикл. При этом, если цикл написан корректно (с учетом, что он может исполняться долго), то внешне это не выглядит, что программа "висит". Винда определяет "висение" программы по тому, что она не отвечает на сообщения, что совершенно на самом деле не значит, что она висит, просто может выполняться какая-то длительная операция. Например, срвременные браузеры на старых (читай относительно медленных) компутерах в какой-то момент при загрузке могут отражаться как зависшие (Не отвечает или Not responding в заголовке окна). Т.е. по твоему вопросу - надо делать примерно так же. Если программа, которую ты мониторишь, твоя, то сделай в ней обработку какого-нибудь твоего сообщения. Монитор посылает его, если в течении какого-то времени/итераций это сообщение не обрабатывается, то убивай процесс. Если программа не твоя, то пробуй посылать какое-нить из стандартных сообщений, которое точно должно обрабатываться, например, WM_PAINT. |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
AndyBogart (20.05.2019)
|
#3
|
|||
|
|||
lmikle, да программа не моя.
Для меня будет достаточно определить, что программа зависла, если она не отвечает допустим 10-20 секунд. Независимо от того работает там что-то в фоне или нет. А как мне перехватить WM_PAINT с другого приложения? |
#4
|
||||
|
||||
Учимся пользоваться гуглом и тп, вот пример с 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
|
|||
|
|||
Благодарю, Лорд Вайрус )
|
#6
|
|||
|
|||
В виртуалке часто определяет работающее приложение как зависшее
если пользую этот код: Код:
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. |