AutoHockKill зависает процесс

Я нашел способ найти зависший процесс, но независимо от того, какой метод я использую, я не могу его убить:

    #Persistent
    Menu, Tray, Icon, User32.dll, 2
    SMTO_NOTIMEOUTIFNOTHUNG := 8      
    Delay = 200                    
    SetTimer, CheckAllWindows, 10
    Return

    CheckAllWindows:
      SetTimer, CheckAllWindows, Off
      WinGet, hWnd, List

      Loop, %hWnd%           {

            ID := hwnd%A_Index%

            DllCall("SendMessageTimeout", UInt,ID, UInt, 0, Int,0, Int,0
                    , UInt, SMTO_NOTIMEOUTIFNOTHUNG, Int,3, "UInt *", Result )

            WinGetTitle, Title, ahk_id %ID%
        PID := DllCall("GetCurrentProcessId")
            IfNotEqual,Result,0,GoSub,Alert

            Sleep %Delay%
                             }
      SetTimer, CheckAllWindows, %Delay%
    Return

Alert: ; This routine can be used to repeat testing & offer a WinKill.
Process, Close, PID
Sleep 50000
Run, "C:\Program Files\sample_file.exe"
Return

Прямо сейчас программа обнаруживает, что процесс завис, и запустит файл, но он не закроется. Я также попробовал WinClose - не повезло. Мысли?

1 ответ

Feren6, я надеюсь, что не подавляю вас, но однажды я вырезал этот текст, и я еще не использовал его, я надеюсь, что он может помочь вам, особенно HSHELL_ENDTASK.

Документированные значения для wParam:

1. HSHELL_WINDOWCREATED
2. HSHELL_WINDOWDESTROYED
3. HSHELL_ACTIVATESHELLWINDOW
4. HSHELL_WINDOWACTIVATED
5. HSHELL_GETMINRECT
6. HSHELL_REDRAW
7. HSHELL_TASKMAN
8. HSHELL_LANGUAGE
9. HSHELL_SYSMENU
10. HSHELL_ENDTASK
11. HSHELL_ACCESSIBILITYSTATE
12. HSHELL_APPCOMMAND
13. HSHELL_WINDOWREPLACED
14. HSHELL_WINDOWREPLACING
15. HSHELL_HIGHBIT
16. HSHELL_FLASH
17. HSHELL_RUDEAPPACTIVATED

lParam отличается по типу в зависимости от значения wParam, полученного. Для большинства значений wParam lParam - это дескриптор окна, который можно использовать как ahk_id %lParam% в командах Window AHK.

Некоторые идеи: оболочка получает HSHELL_GETMINRECT (со структурой shellhook) всякий раз, когда окно свернуто / развернуто. Сценарий может контролировать это, чтобы свернуть окно в трей. Оболочка получает HSHELL_REDRAW, когда окно перерисовывается. Скрипт может отслеживать его, чтобы активировать окно всякий раз, когда его содержимое изменяется.

Я попытался экспериментировать, и вот несколько примеров:

Эксперимент 1:

В Windows XP CTRL+ALT+DEL вызывает диспетчер задач. На форуме было несколько сообщений с просьбой запретить доступ к диспетчеру задач. Следующие сценарии обнаруживают и закрывают диспетчер задач Windows практически мгновенно при его создании.

Код:

настойчивый

SetBatchLines, -1 Процесс, Приоритет,, Высокий

Gui + LastFound hWnd: = WinExist ()

DllCall ("RegisterShellHookWindow", UInt, hWnd) MsgNum: = DllCall ("RegisterWindowMessage", Str, "SHELLHOOK") OnMessage (MsgNum, "ShellMessage") Возврат

ShellMessage( wParam,lParam) { If ( wParam = 1); HSHELL_WINDOWCREATED:= 1 { WinGetTitle, Title, ahk_id %lParam% If ( Title = "Диспетчер задач Windows") { WinClose, ahk_id %lParam%; Запустите, Calc.exe; вместо этого} } }

Эксперимент 2:

Сообщения Hooking Shell обеспечивают надежный способ сохранить трек в последнем активном окне. Смотрите: Как получить ПОСЛЕДНЕЕ активное окно? by r0lZ Следующий скрипт переключает стили TopMost/TopLevel ( Always on Top On/OFF) активного окна.

Код:

настойчивый

Меню, Лоток, Нестандартное меню, Лоток, Добавить, Переключить AOT, Меню ToggleAOT, Лоток, Добавить, Меню, Лоток, Добавить, Перезагрузить, Меню ExitScript, Лоток, Добавить, Выход, Меню ExitScript, Лоток, Подсказка, Переключить меню AOT, Лоток По умолчанию, Переключить AOT

Gui + LastFound DllCall ("RegisterShellHookWindow", UInt, WinExist ()) MsgNum: = DllCall ("RegisterWindowMessage", Str, "SHELLHOOK") OnMessage (MsgNum, "ShellMessage") LastActiveWindowID: = WinActive ("A)

Вернуть; // Конец секции авто-исполнения //

ShellMessage (wParam, lParam) {Global LastActiveWindowID If (wParam = 4 и WinExist ("ahk_id" lParam)) {; HSHELL_WINDOWACTIVATED = 4 LastActiveWindowID: = lParam}}

ToggleAOT: WinSet, AlwaysOnTop, Toggle, ahk_id% LastActiveWindowID% Return

ExitScript: DllCall ("DeregisterShellHookWindow", UInt, hWnd); Я полагаю, с избыточностью! IfEqual, A_ThisMenuItem, перезагрузка, перезагрузка, выход из приложения, возврат

Запустите скрипт. Нажмите на целевое окно, чтобы сфокусировать его. Дважды щелкните значок скрипта в трее. Целевое окно будет переключаться между стилями TopMost и TopLevel.

Эксперимент 3:

У меня есть мультимедийная клавиатура Logitech, и я не установил прилагаемое программное обеспечение. Я использовал свой собственный экранный скрипт, который использовал клавиши VOLUME_UP /DN/MUTE в качестве горячих клавиш для запуска регулировки с помощью команд SoundGet / SoundSet.

Теперь я обнаружил, что Shell уведомляется ( HSHELL_APPCOMMAND) всякий раз, когда я нажимаю клавишу мультимедиа. HiWord of lParam содержит значение нажатой клавиши MM. Поэтому я изменил свой экранный сценарий изменения громкости, чтобы он работал без горячих клавиш или команды SoundSet.

Код: Gui, Color, FFFFFF Gui, -Caption + Border + AlwaysOnTop + ToolWindow + LastFound

hWnd: = WinExist (), DllCall ("RegisterShellHookWindow", UInt, hWnd) MsgNum: = DllCall ("RegisterWindowMessage", Str, "SHELLHOOK") OnMessage (MsgNum, "ShellMessage")

Gui, Добавить, Изображение, x5 y5 w32 h32 Icon4 vIcon1, SndVol32.exe Gui, Добавить, Изображение, x5 y5 w32 h32 Icon5 vIcon2, SndVol32.exe Loop,25 Gui, Добавить, Текст, x+3 w5 h32 Скрытая граница vText%A_Index% 0x4;

Вернуть; // Конец секции Auto-Exexute //

ShellMessage (wParam, lParam) {If (wParam = 12 AND ((lParam >> 16)> = 8 OR (lParam >> 16)<= 10)) {Gui, Показать SoundGet, Громкость, MASTER, VOLUME SoundGet, Mute,, MUTE

 Loop, 25 
   IfLessOrEqual, A_Index, % Round(Volume/4), GuiControl, Show, Text%A_Index%
   Else                                       GuiControl, Hide, Text%A_Index%

 IfEqual, Mute, On, GuiControl, Hide, Icon2
 Else               GuiControl, Show, Icon2

 SetTimer, GuiEscape, 1234
                            }                                      }

GuiEscape: SetTimer, GuiEscape, OFF GUI, Скрыть

Проще говоря, когда wParam равен 12 ( HSHELL_APPCOMMAND), HiWord для lParam содержит одну из следующих констант:

* APPCOMMAND_BROWSER_BACKWARD = 1

APPCOMMAND_BROWSER_FORWARD = 2 APPCOMMAND_BROWSER_REFRESH = 3 APPCOMMAND_BROWSER_STOP = 4 APPCOMMAND_BROWSER_SEARCH = 5 APPCOMMAND_BROWSER_FAVORITES = 6 APPCOMMAND_BROWSER_HOME = 7 APPCOMMAND_VOLUME_MUTE = 8 APPCOMMAND_VOLUME_DOWN = 9 APPCOMMAND_VOLUME_UP = 10 APPCOMMAND_MEDIA_NEXTTRACK = 11 APPCOMMAND_MEDIA_PREVIOUSTRACK = 12 APPCOMMAND_MEDIA_STOP = 13 APPCOMMAND_MEDIA_PLAY_PAUSE = 14 APPCOMMAND_LAUNCH_MAIL = 15 APPCOMMAND_LAUNCH_MEDIA_SELECT = 16 APPCOMMAND_LAUNCH_APP1 = 17 APPCOMMAND_LAUNCH_APP2 = 18 APPCOMMAND_BASS_DOWN = 19 APPCOMMAND_BASS_BOOST = 20 APPCOMMAND_BASS_UP = 21 APPCOMMAND_TREBLE_DOWN = 22 APPCOMMAND_TREBLE_UP = 23 APPCOMMAND_MICROPHONE_VOLUME_MUTE = 24 APPCOMMAND_MICROPHONE_VOLUME_DOWN = 25 APPCOMMAND_MICROPHONE_VOLUME_UP = 26 APPCOMMAND_HELP = 27 APPCOMMAND_FIND = 28 APPCOMMAND_NEW = 29 APPCOMMAND_OPEN = 30 APPCOMMAND_CLOSE = 31 APPCOMMAND_SAVE = 32 APPCOMMAND_PRINT = 33 APPCOMMAND_UNDO = 34 APPCOMMAND_REDO = 35 APPCOMMAND_COPY = 36 APPCOMMAND_CUT = 37 APPCOMMAND_PAS ТЕ = 38 APPCOMMAND_REPLY_TO_MAIL = 39 APPCOMMAND_FORWARD_MAIL = 40 APPCOMMAND_SEND_MAIL = 41 APPCOMMAND_SPELL_CHECK = 42 APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE = 43 APPCOMMAND_MIC_ON_OFF_TOGGLE = 44 APPCOMMAND_CORRECTION_LIST = 45

Эксперимент 4:

Пытаясь изучить и понять сообщения, я написал этого грубого шпиона Shell, чтобы отслеживать сообщения, получаемые Shell:

Код:

настойчивый

Меню, Лоток, Добавить меню, Лоток, Добавить, & Показать, Меню GuiShow, Лоток, По умолчанию, & Показать Gui, Шрифт, s9, Курьер Новый

Gui +ToolWindow +AlwaysOnTop +Resize +LastFound hWnd:= WinExist() DllCall( "RegisterShellHookWindow", UInt,hWnd) MsgNum:= DllCall( "RegisterWindowMessage", Str,"SHELLHOOK") OnMessage( MsgNum ")

Gui, Добавить, Изменить, w512 h512 vMsgs hwndEditC + ReadOnly Gui, Show, x10 y10, Shell Spy

MsgNames = (HSHELL_WINDOWCREATED HSHELL_WINDOWDESTROYED HSHELL_ACTIVATESHELLWINDOW HSHELL_WINDOWACTIVATED HSHELL_GETMINRECT HSHELL_REDRAW HSHELL_TASKMAN HSHELL_LANGUAGE HSHELL_SYSMENU HSHELL_ENDTASK HSHELL_ACCESSIBILITYSTATE HSHELL_APPCOMMAND HSHELL_WINDOWREPLACED HSHELL_WINDOWREPLACING HSHELL_HIGHBIT HSHELL_FLASH HSHELL_RUDEAPPACTIVATED)

AppCommands = (APPCOMMAND_BROWSER_BACKWARD = 1 APPCOMMAND_BROWSER_FORWARD = 2 APPCOMMAND_BROWSER_REFRESH = 3 APPCOMMAND_BROWSER_STOP = 4 APPCOMMAND_BROWSER_SEARCH = 5 APPCOMMAND_BROWSER_FAVORITES = 6 APPCOMMAND_BROWSER_HOME = 7 APPCOMMAND_VOLUME_MUTE = 8 APPCOMMAND_VOLUME_DOWN = 9 APPCOMMAND_VOLUME_UP = 10 APPCOMMAND_MEDIA_NEXTTRACK = 11 APPCOMMAND_MEDIA_PREVIOUSTRACK = 12 APPCOMMAND_MEDIA_STOP = 13 APPCOMMAND_MEDIA_PLAY_PAUSE = 14 APPCOMMAND_LAUNCH_MAIL = 15 APPCOMMAND_LAUNCH_MEDIA_SELECT = 16 APPCOMMAND_LAUNCH_APP1 = 17 APPCOMMAND_LAUNCH_APP2 = 18 APPCOMMAND_BASS_DOWN = 19 APPCOMMAND_BASS_BOOST = 20 APPCOMMAND_BASS_UP = 21 APPCOMMAND_TREBLE_DOWN = 22 APPCOMMAND_TREBLE_UP = 23 APPCOMMAND_MICROPHONE_VOLUME_MUTE = 24 APPCOMMAND_MICROPHONE_VOLUME_DOWN = 25 APPCOMMAND_MICROPHONE_VOLUME_UP = 26 APPCOMMAND_HELP = 27 APPCOMMAND_FIND = 28 APPCOMMAND_NEW = 29 APPCOMMAND_OPEN = 30 APPCOMMAND_CLOSE = 31 APPCOMMAND_SAVE = 32 APPCOMMAND_PRINT = 33 APPCOMMAND_UNDO = 34 APPCOMMAND_REDO = 35 APPCOMM AND_COPY = 36 APPCOMMAND_CUT = 37 APPCOMMAND_PASTE = 38 APPCOMMAND_REPLY_TO_MAIL = 39 APPCOMMAND_FORWARD_MAIL = 40 APPCOMMAND_SEND_MAIL = 41 APPCOMMAND_SPELL_CHECK = 42 APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE = 43 APPCOMMAND_MIC_ON_OFF_TOGGLE = 44 APPCOMMAND_CORRECTION_LIST = 45) Возврат

ShellMessages( wP,lP) { Global EditC Global mVal:= lP GuiControlGet, Msgs Рутина:= GetMessageName( wP) IfEqual, Рутина, SetEnv, Рутина, НЕИЗВЕСТНО GuiControl, Msgs,% Msgs "nn "Рутина" [" wP "]"Если IsLabel(Рутина) GoSub, % Рутина% ControlSend,, ^ {End}, ahk_id% EditC%}

GetMessageName (FieldN = 0) {Глобальный цикл MsgNames, Parse, MsgNames, `n IfEqual, A_Index,% FieldN%, Return, A_LoopField}

GetAppCommand (FieldN = 0) {Глобальные AppCommands Loop, Parse, AppCommands, `n IfEqual, A_Index, %FieldN%, Return, A_LoopField }

НЕИЗВЕСТНО: HSHELL_WINDOWCREATED: HSHELL_WINDOWACTIVATED: HSHELL_WINDOWDESTROYED: HSHELL_REDRAW: HSHELL_FLASH: HSHELL_ENDTASK: HSHELL_WINDOWREPLACING: HSHELL_WINDOWREPLEDED
HSHELL_RUDEAPPACTIVATED:

WinGetTitle, Title, ahk_id% mVal% WinGetClass, Class, ahk_id% mVal% GuiControlGet, Msgs GuiControl,, Msgs,% Msgs "nnhWndt: " WinExist("ahk_id" mVal) "nTitlet: " Title "nClass`t: "Класс

Вернуть

HSHELL_GETMINRECT: возврат

HSHELL_APPCOMMAND: GuiControlGet, Msgs GuiControl,, Msgs, % Msgs " // " GetAppCommand( mVal >> 16) Возврат

GuiClose: Gui, Показать, Скрыть Вернуться

GuiShow: Gui, Показать, Вернуться

Это не исчерпывающе, но полезно понять, как все работает.

Запустив приведенный выше код, запустите калькулятор и измените его со стандартного на научный режим. Вы обнаружите, что окно Калькулятор разрушается и создается снова, что приводит к изменению дескриптора. (Я не знал этого)

Интересно, что я обнаружил, что оболочка получает недокументированное значение ( AFAIK) 0x8006 ( 32774) всякий раз, когда окно мигает кнопкой заголовка панели задач / панели задач. Следующий код активирует вспыхивающее окно: (не уверен, будет ли оно работать для всех):

Код: Gui + LastFound

hWnd: = WinExist (), DllCall ("RegisterShellHookWindow", UInt, hWnd) MsgNum: = DllCall ("RegisterWindowMessage", Str, "SHELLHOOK") OnMessage (MsgNum, "ShellMessage")

Вернуть; // Конец секции авто-исполнения //

ShellMessage (wParam, lParam) {If (wParam = 0x8006); 0x8006 - это 32774, как показано в Spy! { WinActivate, ahk_id %lParam% } }

Другие вопросы по тегам