C++使用WH_SHELL钩子开发自定义Windows外壳(explorer替代程序)咨询
1. WH_SHELL钩子机制相关
- 跨进程监听全局WH_SHELL事件必须将钩子过程封装在DLL中,你当前的实现方向是对的
- 调用
SetWindowsHookEx时传入dwThreadId = 0注册全局钩子后,系统会自动将你的钩子DLL注入到所有后续创建的、具备消息循环的目标进程中,不需要你手动处理注入逻辑,也不需要依赖进程主动通知 - 常见钩子不生效的排查点:注意DLL的位数匹配,64位系统下32位进程无法加载64位DLL,反之亦然,若要覆盖全平台需要分别编译32/64位两个版本的钩子DLL
- 不需要将钩子绑定到特定进程,全局钩子的生命周期和你调用
SetWindowsHookEx的宿主进程绑定,宿主进程退出前调用UnhookWindowsHookEx即可清理
2. 默认Shell配置相关
- 替换默认Shell仅修改注册表是可行的:修改
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon下的Shell值为你的程序绝对路径即可,若要仅对当前用户生效,可修改HKEY_CURRENT_USER下同路径的Shell值,优先级更高 SystemParametersInfo必须在你程序的主窗口创建完成后、调用SetWindowsHookEx之前执行,作用是告知系统当前进程是活跃Shell,需要接收Shell类系统通知- 标准调用参数:
// hWnd为你的程序顶层主窗口句柄,必须有效不能为NULL SystemParametersInfo(SPI_SETSHELLWINDOW, 0, (LPVOID)hWnd, SPIF_SENDCHANGE); - explorer.exe的调用参数和上述标准写法一致,传入的是其桌面顶层窗口(Progman窗口)的句柄
- 不建议的错误配置:
- 未创建主窗口就调用该API,传入NULL或无效句柄,导致系统无法识别你的Shell身份
- 调用后销毁了主窗口未重新调用该API更新句柄
- 随意修改其他SPI参数(如SPI_SETWORKAREA),导致系统工作区配置异常
3. DLL调试输出方案
- 最简便的方案是使用
OutputDebugString输出调试信息,直接在DLL的钩子过程中调用即可,输出内容不会和主控制台混淆,使用系统自带的DebugView工具就能筛选查看所有进程的调试输出,还可以给输出内容加固定前缀区分是DLL的日志 - 不需要额外工具的话可以在DLL中直接写本地日志文件,每次输出追加写入到固定路径的TXT文件中,比如
C:\shell_hook_log.txt,写入后立即关闭文件句柄,就算程序崩溃也不会丢失太多日志 - 注:DLL可以输出到主控制台,只要主程序已经初始化了控制台环境,直接调用printf/cout即可,只是会和主程序日志混在一起,不推荐使用
内容的提问来源于stack exchange,提问作者NalydZ
相关产品推荐
相关产品推荐

