Вопрос 1: Как система мониторит когда приложение зависло? Я слышал что окну отправляется timeout-сообщение, если время ожидания ответа превышено или ответ так и не был получен, то приложение признается зависшим, как можно в своей программе быстро реагировать на зависание других приложений? ну например с целью предложения их завершения (чтобы пользователь не лез в диспетчер задач) Вопрос 2: Так же интересно узнать о возможностях мониторинга загрузки ЦП и оперативы приложениями в целях реагирования на это программы. Если только драйвером, то можете не отвечать (я надеюсь на ассемблерный код) Вопрос 3 (немного не по теме): Какой параметер нужно передать в NtShutdownSystem из ntdll чтобы перезагрузить компьютер, а то у меня высвечивается окно выбора (Жд. режим, Выключение или Перезагрузка)?
seiko 1) Мои мысли. Могу и ошибаться. Переписать виндовс. В часности систему планирования процессов. Другого выхода я не вижу. Для быстрой реакции нужен процесс с высшим приоритетом. Проблема может быть и в зависании драйвера. Так что лучши иметь драйвер с высшим приоритетом. 2) Этот вопрос задают часто. Так что ответ можно легко найти. 3) Незнаю, справку надо читать.
Microsoft рекомендует использовать для этого SendMessageTimeout(). Существует также ряд недокументированных функций, подробнее см. в статье Как определить, что приложение не отвечает?. Сие обсуждалось неоднократно, и здесь и на RSDN'е. Так что - в поиск! Здесь ты что-то путаешь. NtShutdownSystem() - это вызов ядра, никак не связанный с графической подсистемой. Так что вызывать появление какого-то окна оно никак не может. Предполагаю, что ты спутал её с InitiateSystemShutdown(). Если окно не нужно, может быть достаточно будет ExitWindowsEx() ? Если нужно именно NtShutdownSystem(), то вот то, что тебе поможет: Код (Text): typedef enum _SHUTDOWN_ACTION { ShutdownNoReboot, ShutdownReboot, ShutdownPowerOff } SHUTDOWN_ACTION, *PSHUTDOWN_ACTION; NTSYSAPI NTSTATUS NTAPI NtShutdownSystem( IN SHUTDOWN_ACTION Action );
Вот прототип программы, пока только по зависаниям, пишу на дельфе, думаю Win Api везде одинаковая, вопрос такой это будет работать? Код (Text): program Hungery; uses Windows, blocking; ///мой модуль, рабочий Var h:hwnd; id:cardinal; function IsHungAppWindow(hwnd:hwnd):BOOL; stdcall; external 'user32.dll'; function MesFunc(p:pointer):dword; Var k:hwnd; s:string; begin result:=0; k:=hwnd(p^); s:=FindProcessNamebyWindowID(k); ///функции с Find из модуля blocking, хорошо укорачивают код If MessageBox(0,PChar('Приложение '+s+' зависло. Завершить его работу?'), 'Зависшее приложение',MB_OKCANCEL) = MB_OK then terminateprocess(FindProcessHandlebyWindowID(k),0); end; function EnumWindowsProc(hwnd:hwnd; lparam:LPARAM):BOOL; begin If IsHungAppWindow(hwnd) then begin h:=hwnd; beginthread(nil,1024,@MesFunc,@h,0,id); end; result:=true; end; begin repeat EnumWindows(@EnumWindowsProc,0); Delay(500); until false; end. Для тех кому лень разбираться в коде пересказываю алгоритм: С помощью EnumWindows перебираются все окна, в EnumWindowProc с помощью функции IsHungAppWindow выесняется зависло приложение или нет, если да, создается поток с диалоговым окном, которое и сообщает о зависании и предлагает завершить работу программы (в этот поток передается id окна, по которому вычисляется имя исполняемого файла приложения для информирования пользователя и хэндл приложения для его возможного завершения) Кстати, можно ли как-нибудь отфильтровать окна, чтобы не все из них проверять на зависание, ведь куча системных окон редко виснет?
По-моему моя прога не пашет, поскольку когда открываю сетевое окружение и шелл виснет где-то секунд 20, а реакции никакой Появился вопрос: а как можно определить какой из процессов в данный момент времени сколько ЦП жрет (как это делается в диспетчере задач)? аналогично и про оперативу? P.S. Насчет фильтрации окон - я убрал из проверки на зависон окна с именами M и Default IME, а также без имен