【问题标题】:Autohotkey kill hung processAutohotkey 杀死挂起的进程
【发布时间】:2012-05-24 20:48:43
【问题描述】:

我发现了一种查找挂起进程的方法,但无论我使用哪种方法,我似乎都无法杀死它:

    #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 - 没有运气。想法?

【问题讨论】:

    标签: process kill autohotkey hung


    【解决方案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 的窗口命令中用作 ahk_id %lParam%。

    一些想法: 每当窗口被最小化/最大化时,shell 都会接收 HSHELL_GETMINRECT(带有 shellhook 结构)。脚本可能会监视它以将窗口最小化到托盘。 当窗口被重绘时,shell 接收 HSHELL_REDRAW。脚本可以监视它以在其内容更改时激活窗口。

    我尝试过,这里有一些例子:

    实验一:

    在 Windows XP 中,CTRL+ALT+DEL 会带来任务管理器。论坛已经看到一些帖子请求拒绝访问任务管理器的方法。 以下脚本在创建时几乎立即检测并关闭 Windows 任务管理器。

    代码:

    持久

    SetBatchLines, -1 进程、优先级、高

    桂 +LastFound hWnd := WinExist()

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

    ShellMessage(wParam,lParam){ 如果(wParam = 1); HSHELL_WINDOWCREATED := 1 { WinGetTitle,标题,ahk_id %lParam% 如果(标题=“Windows 任务管理器”) { WinClose, ahk_id %lParam% ;运行,Calc.exe;反而 } } }

    实验 2:

    Hooking Shell 消息提供了一种可靠的方法来跟踪上一个活动窗口。 请参阅:如何检索最后一个活动窗口?由 r0lZ 以下脚本切换活动窗口的 TopMost/TopLevel 样式 ( Always on Top On/OFF )。

    代码:

    持久

    菜单、托盘、NoStandard 菜单、托盘、添加、切换 AOT、切换 AOT 菜单,托盘,添加, 菜单、托盘、添加、重新加载、退出脚本 菜单、托盘、添加、退出、退出脚本 菜单、托盘、提示、切换 AOT 菜单、托盘、默认、切换 AOT

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

    返回; // 自动执行部分结束 //

    ShellMessage(wParam, lParam) { 全局 LastActiveWindowID If ( wParam = 4 And WinExist( "ahk_id " lParam ) ) { ; HSHELL_WINDOWACTIVATED = 4 LastActiveWindowID := lParam } }

    切换AOT: WinSet、AlwaysOnTop、切换、ahk_id %LastActiveWindowID% 返回

    退出脚本: DllCall("DeregisterShellHookWindow", UInt,hWnd) ;冗余,我猜! IfEqual,A_ThisMenuItem,重新加载,重新加载 退出应用程序 返回

    运行脚本。 单击目标窗口以将其聚焦。 双击脚本托盘图标。 目标窗口将在 TopMost 和 TopLevel 样式之间切换。

    实验 3:

    我有一个罗技多媒体键盘,但没有安装它附带的软件。我使用的是我自己的 OSD 脚本,它使用 VOLUME_UP /DN/MUTE 键作为热键来触发 SoundGet / SoundSet 命令的调整。

    现在我发现,每当我按下多媒体键时,Shell 都会收到通知 (HSHELL_APPCOMMAND)。 lParam 的 HiWord 包含按下的 MM 键的值。所以我修改了我的 Volume Change OSD 脚本,让它在没有 HotKeys 或 SoundSet 命令的情况下工作。

    代码: 桂,颜色,FFFFFF Gui, -Caption +Border +AlwaysOnTop +ToolWindow +LastFound

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

    Gui, Add, Picture, x5 y5 w32 h32 Icon4 vIcon1, SndVol32.exe Gui, Add, Picture, x5 y5 w32 h32 Icon5 vIcon2, SndVol32.exe 循环,25 Gui, Add, Text, x+3 w5 h32 隐藏边框 vText%A_Index% 0x4 ;

    返回; // 自动执行部分结束 //

    ShellMessage(wParam,lParam){ 如果 ( wParam = 12 AND ( (lParam>>16) >= 8 OR (lParam>>16)

     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: 设置定时器,GuiEscape,关闭 贵,躲

    简单地说,当 wParam 为 12 ( HSHELL_APPCOMMAND ) 时,lParam 的 HiWord 包含以下常量之一:

    * 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_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

    实验 4:

    在尝试研究和理解消息时,我编写了这个粗略的 Shell 间谍来监视 Shell 接收到的消息:

    代码:

    持久

    菜单、托盘、添加 Menu,Tray,Add,&Show, GuiShow 菜单、托盘、默认、&显示 Gui, Font, s9, Courier New

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

    GUI,添加,编辑,w512 h512 vMsgs hwndEditC +ReadOnly Gui, Show, x10 y10, 壳牌间谍

    消息名称 = ( 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 )

    应用命令 = ( 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_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){ 全球编辑C 全局 mVal := lP GuiControlGet,消息 例程 := GetMessageName( wP ) IfEqual,Routine,, SetEnv, Routine, UNKNOWN GuiControl,, Msgs, % Msgs "nn" 例程 " [" wP "]" If IsLabel(例程) GoSub,%例程% ControlSend,, ^{End}, ahk_id %EditC% }

    GetMessageName(FieldN=0) { 全局消息名称 循环、解析、MsgNames、`n IfEqual, A_Index, %FieldN%, 返回, A_LoopF​​ield }

    GetAppCommand(FieldN=0) { 全局 AppCommands 循环、解析、AppCommands、`n IfEqual, A_Index, %FieldN%, 返回, A_LoopF​​ield }

    未知: HSHELL_WINDOW创建: HSHELL_WINDOWACTIVATED: HSHELL_WINDOWDESTROYED: HSHELL_REDRAW: HSHELL_FLASH: HSHELL_ENDTASK: HSHELL_WINDOWREPLACING: HSHELL_WINDOWREPLACED:
    HSHELL_RUDEAPPACTIVATED:

    WinGetTitle, 标题, ahk_id %mVal% WinGetClass, 类, ahk_id %mVal% GuiControlGet,消息 GuiControl,, 消息 , % Msgs "nnhWndt: " WinExist("ahk_id" mVal) "nTitlet: " Title "nClass`t: "类

    返回

    HSHELL_GETMINRECT: 返回

    HSHELL_APP 命令: GuiControlGet,消息 GuiControl,, Msgs, % Msgs " // " GetAppCommand( mVal >> 16 ) 返回

    Gui关闭: Gui, 显示, 隐藏 返回

    桂秀: 桂秀秀 返回

    这并不详尽,但有助于了解这些东西的工作原理。

    运行上述代码后,运行计算器并将其从标准模式更改为科学模式。 会发现计算器窗口被破坏并重新创建导致句柄发生变化。 (我不知道)

    有趣的是,我发现每当窗口闪烁其标题栏/任务栏按钮时,Shell 都会收到一个未记录的 (AFAIK) 值 0x8006 ( 32774 )。以下代码激活了一个正在闪烁的窗口:(不确定它是否适用于所有人):

    代码: 桂+LastFound

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

    返回; // 自动执行部分结束 //

    ShellMessage(wParam,lParam) { 如果(wParam = 0x8006); 0x8006 是 32774,如 Spy! { WinActivate, ahk_id %lParam% } }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-12
      • 2014-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-31
      • 2017-08-05
      • 2017-05-20
      相关资源
      最近更新 更多