我发现了一种找到挂起进程的方法,但无论我使用什么方法,我似乎无法杀死它:
#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 - 没有运气。想法?
答案 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_LoopField }
GetAppCommand(FieldN = 0){ 全球AppCommands Loop,Parse,AppCommands,`n IfEqual,A_Index,%FieldN%,Return,A_LoopField }
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% } }