libuiohook 全局键盘鼠标钩子 C 库入门指南
【免费下载链接】libuiohookA multi-platform C library to provide global keyboard and mouse hooks from userland.项目地址: https://gitcode.com/gh_mirrors/li/libuiohook
libuiohook 让你不装内核驱动、仅靠用户态程序,就能截获整个系统里发生的按键与鼠标动作,同时覆盖 Linux、Windows、macOS 三端。想开发自动化、宏命令或输入监控工具的人,读这篇文章就能把库编译出来并看懂事件是怎么流到你手里的。
先动手:构建时要装哪些依赖
结论先行:只要 CMake 3.10 以上加任意 C99 编译器,代码本身没有第三方运行时库。真正麻烦的是 Linux——它通过 X11 的 XRecord 扩展抓事件,所以要装libx11-dev、libxtst-dev、libxinerama-dev等一整套 X 开发包;macOS 和 Windows 则直接用系统自带的框架,无需额外安装。
CMakeLists.txt 开头的平台判断决定了源码从哪个目录编译:Windows 走src/windows/,macOS 走src/darwin/,其余一律按src/x11/处理。拿到源码后一条标准流程即可出库:
git clone https://gitcode.com/gh_mirrors/li/libuiohook cd libuiohook mkdir build && cd build # 打开 BUILD_DEMO 会顺带编译 4 个示例程序,产物装进 ../dist cmake -S .. -DBUILD_SHARED_LIBS=ON -DBUILD_DEMO=ON -DCMAKE_INSTALL_PREFIX=../dist cmake --build . --target install装完库之后,别的项目可以用 CMake 找包或 pkg-config(uiohook.pc会一起生成)来链接它,这就是 pc/uiohook.pc.in 存在的意义。
从哪个文件读起:X11 钩子的事件链条
想看懂核心逻辑,直接读 Linux 版的 src/x11/input_hook.c,整条链路只有三个角色:
hook_run():分配一块状态区(修饰键掩码、鼠标连击计数等),然后调xrecord_start()进入 XRecord 监听循环并阻塞,直到钩子被移除才返回。hook_event_proc():X server 每推来一条原始记录,就在这个回调里把它翻译成统一的uiohook_event结构,再交给dispatch_event()转发给你注册的函数。hook_stop():校验并关闭 XRecord 上下文,使hook_run()解除阻塞、释放资源。
hook_run()的骨架如下,注释已按阅读顺序重写:
int hook_run() { hook = malloc(sizeof(hook_info)); // 给本次钩子开一个状态容器 // 修饰键掩码、鼠标按键与连击时间全部清零 hook->input.mask = 0x0000; int status = xrecord_start(); // 启动 XRecord 循环并阻塞,等待 hook_stop free(hook); // 钩子结束后清掉状态区 return status; // 0x00 成功,其余为平台相关错误码 }你注册的回调不是直接收到 X11 原始事件,而是经过dispatch_event()这层统一后的结构体,字段含义在唯一的公共头文件 include/uiohook.h 里查得到——uiohook_event用 union 装下键盘、鼠标、滚轮三类数据,VC_ESCAPE、MASK_CTRL_L这些虚拟键码与修饰掩码也都在这里定义。
改功能时该翻哪条路径
遇到问题前,用这张表先定位,比翻全目录快得多:
| 路径 | 作用 |
|---|---|
| include/uiohook.h | 唯一对外头文件:事件结构体、虚拟键码、hook_run/hook_stop声明 |
| src/x11/input_hook.c | Linux 实现核心:XRecord 抓事件并翻译成统一事件 |
| src/x11/post_event.c | 反向注入:通过 XTest 把虚拟按键/鼠标事件送回系统 |
| src/logger.c | 内部日志的开关与回调桥接,hook_set_logger_proc落在这里 |
| demo/demo_hook.c | 最短可用范例:注册回调后逐条打印事件,按 Esc 退出 |
| test/uiohook_test.c | minunit 测试入口,加-DENABLE_TEST=ON后随主库一起编译 |
Windows 与 macOS 目录下有同名的四件套(input_hook.c、post_event.c等),结构一一对应,读熟 x11 版本后切换平台只需要看系统 API 的差异部分。man/目录里的手册页则解释了各hook_get_*系统属性函数,用到时再查即可。
接下来做什么
这篇导读把"编译 → 事件流转 → 路径定位"串完了。下一步建议开两个终端验证:一个用-DENABLE_TEST=ON重新构建并跑测试,一个直接运行demo_hook,边敲键盘边看它打印的事件流——你会发现 Esc 触发hook_stop()的那一段正好对应前面讲的链路。若想深入平台细节,src/x11/input_helper.c里的按键码翻译表是下一个值得细读的地方。
【免费下载链接】libuiohookA multi-platform C library to provide global keyboard and mouse hooks from userland.项目地址: https://gitcode.com/gh_mirrors/li/libuiohook
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考