Autohotkey杀死了进程

时间:2012-05-22 18:06:10

标签: process kill autohotkey hung

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

    #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 个答案:

答案 0 :(得分: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。只要内容发生变化,脚本就可以监视它以激活窗口。

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

实验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){   如果(wParam = 1); HSHELL_WINDOWCREATED:= 1      {        WinGetTitle,标题,ahk_id%lParam%        如果(标题=" Windows任务管理器")          {            WinClose,ahk_id%lParam%          ;运行,Calc.exe;代替          }      } }

实验2:

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

代码:

持久性

菜单,托盘,NoStandard 菜单,托盘,添加,切换AOT,切换AOT 菜单,托盘,添加, 菜单,托盘,添加,重新加载,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   如果(wParam = 4和WinExist(" ahk_id" lParam)){; HSHELL_WINDOWACTIVATED = 4        LastActiveWindowID:= lParam   } }

ToggleAOT:   WinSet,AlwaysOnTop,Toggle,ahk_id%LastActiveWindowID% 返回

ExitScript:   DllCall(" DeregisterShellHookWindow",UInt,hWnd);我想是多余的!   IfEqual,A_ThisMenuItem,Reload,Reload   ExitApp命令 返回

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

实验3:

我有一台Logitech多媒体键盘,并没有安装随附的软件。我使用自己的OSD脚本,使用VOLUME_UP / DN / MUTE键作为热键来触发SoundGet / SoundSet命令的调整。

现在我发现,只要我按下多媒体键,就会通知Shell(HSHELL_APPCOMMAND)。 lParam的HiWord包含按下的MM键的值。所以我已经改变了我的音量变化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,添加,图片,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 Hidden Border vText%A_Index%0x4;

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

ShellMessage(wParam,lParam){   如果(wParam = 12 AND((1Param> 16)> = 8 OR(lParam> 16)< = 10)){      桂,秀      SoundGet,音量,MASTER,音量      SoundGet,静音,静音

 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,Hide

简单地说,当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收到的消息时:

代码:

持久性

菜单,托盘,添加 菜单,托盘,添加和显示,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,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 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){   全球EditC   全局mVal:= lP   GuiControlGet,Msgs   例程:= GetMessageName(wP)   IfEqual,Routine ,, SetEnv,Routine,UNKNOWN   GuiControl ,, Msgs,%Msgs" n n"常规" [" wP"]"   如果是IsLabel(常规)      GoSub,%例程%   ControlSend ,, ^ {End},ahk_id%EditC% }

GetMessageName(FieldN = 0){   全球MsgNames   Loop,Parse,MsgNames,`n         IfEqual,A_Index,%FieldN%,Return,A_LoopF​​ield }

GetAppCommand(FieldN = 0){   全球AppCommands   Loop,Parse,AppCommands,`n         IfEqual,A_Index,%FieldN%,Return,A_LoopF​​ield }

UNKNOWN: HSHELL_WINDOWCREATED: HSHELL_WINDOWACTIVATED: HSHELL_WINDOWDESTROYED: HSHELL_REDRAW: HSHELL_FLASH: HSHELL_ENDTASK: HSHELL_WINDOWREPLACING: HSHELL_WINDOWREPLACED:
HSHELL_RUDEAPPACTIVATED:

WinGetTitle,Title,ahk_id%mVal%  WinGetClass,Class,ahk_id%mVal%  GuiControlGet,Msgs  GuiControl ,, Msgs    ,%Msgs" n nhWnd t: " WinExist("ahk_id" mVal) " nTitle t: " Title " nClass`t:"类

返回

HSHELL_GETMINRECT: 返回

HSHELL_APPCOMMAND:  GuiControlGet,Msgs  GuiControl ,, Msgs,%Msgs" //" GetAppCommand(mVal>> 16) 返回

GuiClose:  桂,秀,隐藏 返回

GuiShow:  桂,秀, 返回

这并不详尽,但有助于理解这些东西是如何运作的。

运行上面的代码,运行计算器并将其从标准模式更改为科学模式。 人们会发现计算器窗口被销毁并再次创建,导致句柄发生变化。 (我不知道)

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

代码: Gui + LastFound

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

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

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