尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

kanata Windows Key Tester 深度指南:在 Windows 下排查与测试键盘按键码映射

kanata Windows Key Tester 深度指南:在 Windows 下排查与测试键盘按键码映射 kanata Windows Key Tester 深度指南在 Windows 下排查与测试键盘按键码映射【免费下载链接】kanataImprove keyboard comfort and usability with advanced customization项目地址: https://gitcode.com/GitHub_Trending/ka/kanatakanata 是跨平台的多层键盘自定义key remapping工具其按键抽象统一采用 Linux 输入子系统风格的 OsCode 体系但 Windows 键盘按键到这些按键码之间并非一一对应总有一些新键盘或特殊按键媒体键、日文键、小键盘扩展键尚未被 kanata 收录。windows_key_tester正是为解决这一问题而生的 Windows 版按键测试工具本文将以 windows_key_tester/README.md 为骨架结合其源码与构建脚本讲解它的用途、构建运行方式、两种采集后端的工作原理、日志输出解读以及如何借助它向 kanata 补齐新的按键映射。读完本文你将能够独立构建并运行该工具读懂其输出并利用它定位 Windows 下未被识别的按键码。一、为什么 kanata 需要 Windows 按键测试器kanata 的核心是对键盘事件进行捕获、改写与转发。为了跨平台统一kanata 内部使用一套以 Linux 内核输入子系统evdevKEY_*常量为基础的 OsCode 集合在 windows_key_tester/src/windows/interception.rs 中可以看到这套枚举的完整定义其数值与 Linux 输入事件码一一对应。因此Windows 平台上每一枚按键都要先映射到这套 OsCode 空间之后才能参与层切换、组合键、宏等逻辑。但 Windows 的按键信息来源复杂既可以是虚拟键码Virtual Key CodeVK也可以是扫描码Scan Code且同一物理键在不同布局美式/日式/ISO下产生的码值不同。部分按键例如多功能媒体键、OEM 键、日文专用键的码值在 kanata 的映射表中可能尚未收录。README 明确指出这个工具的目的This can be used to help test keyboard-keycode mappings in Windows that may not yet be listed in kanata. For Linux, use the existing evtest.也就是说它的定位就是Windows 版的 evtest读取键盘事件、打印事件信息然后原样转发给操作系统继续处理这一点在 main.rs 顶部注释 中有明确说明从而以零副作用的方式观测按键到底产生了什么码。Linux 用户则继续使用系统自带的evtest完成同样的排查工作。二、构建与运行windows_key_tester是 kanata 工作区的一个成员 crate在根目录 Cargo.toml 的members列表中声明包版本为 0.3.0采用 LGPL-3.0 许可见 windows_key_tester/Cargo.toml。因此它可以直接复用工作区的依赖缓存进行构建# 默认构建LLHook 后端见下文两种采集后端 cargo build -p windows_key_tester # 启用 Interception 驱动后端 cargo build -p windows_key_tester --features interception_driver # 启用 winiov2 扫描码模式依赖 kanata 主 crate cargo build -p windows_key_tester --features winiov2构建产物位于target/debug/windows_key_tester.exeRelease 请加--release。需要注意该工具只能在 Windows 上真正工作。在非 Windows 平台编译运行会直接打印Hello world! Wrong OS. Doing nothing.后退出见 main.rs。若使用interception_driver特性运行前必须完成 Interception 驱动安装仓库assets/Interception.zip中附带了驱动压缩包安装细节可参考 docs/interception.md未安装时程序会在初始化时通过expect抛出明确提示见 interception.rs。运行方式在终端中直接执行windows_key_tester.exe启动后程序的典型流程如下对应 windows.rs初始化日志系统并打印版本号windows_key_tester v0.3.0 starting输出Sleeping for 2s. Please release all keys and dont press additional ones.休眠 2 秒等待用户松开所有按键、避免误录进入采集后端当用户按键时实时打印事件信息退出后提示Press any key to exit等待用户按任意键关闭窗口见 main.rs。三、命令行参数与日志级别工具使用 clap 解析命令行参数目前提供两个开关见 windows.rs参数长选项说明-d--debug开启 Debug 级别日志-t--trace开启 Trace 级别日志且隐含--debug日志级别映射规则见 windows.rs默认不带任何参数Info此时按键事件日志已经可用加--debugDebug加--traceTrace同时覆盖 Debug。日志输出通过simplelog写入终端TerminalMode::Mixed、ANSI 颜色并尝试将时间戳偏移设置为本地时区失败时仅打印警告而不中断windows.rs。四、两种事件采集后端从 windows.rs 可以看到后端由 feature 决定默认编译llhook模块启用interception_driver时编译interception模块。二者共享同一个start()入口签名。4.1 LLHook默认的低级键盘钩子默认后端基于 Windows 低级键盘钩子WH_KEYBOARD_LL实现源码位于 windows_key_tester/src/windows/llhook.rs这一抽象源自 kbremap 项目。其工作要点通过SetWindowsHookExW(WH_KEYBOARD_LL, ...)安装线程级低级键盘钩子llhook.rs钩子结构体KeyboardHook在Drop时自动调用UnhookWindowsHookEx注销钩子避免泄漏回调hook_proc从KBDLLHOOKSTRUCT中提取虚拟键码vkCode与按键状态标志LLKHF_UP是否抬起、LLKHF_INJECTED是否由程序注入组装成InputEvent { code, up }并打印llhook.rs打印后立即调用CallNextHookEx将事件原样交还给操作系统因此不影响正常输入关键前提低级键盘钩子依赖消息循环才能工作所以start()会调用native_windows_gui::init()并进入dispatch_thread_events()事件循环llhook.rs同时通过AttachConsole(ATTACH_PARENT_PROCESS)挂接父控制台以显示调试/panic 输出。winiov2 特性切换到扫描码路径当启用winiov2特性时钩子回调不再直接采用虚拟键码而是改用kanata_state_machine::oskbd::u16_to_osc将扫描码并携带 E0 扩展标记转换为 OsCode转换失败时才回退到vkCodellhook.rs。这体现了 kanata 两种读取模式win_llhook_read_scancodesvswin_sendinput_send_scancodes在测试工具上的对应实现。相关转换函数定义在 src/oskbd/mod.rs。4.2 Interception驱动级键盘过滤可选启用interception_driver特性后工具改用仓库内interception/目录维护的kanata-interceptionRust 封装库直接与 Interception 驱动通信见 windows_key_tester/src/windows/interception.rs。流程为Interception::new()初始化驱动失败时提示检查驱动安装set_filter(ic::is_keyboard, KeyFilter::all())设置过滤器只关注所有键盘设备循环中wait_with_timeout等待设备事件receive批量读取最多 32 个 stroke逐个打印后通过send原样回写interception.rs。Interception 后端天然携带扫描码与 E0/E1 状态位KeyState::E0/KeyState::E1因此Stroke → OsCode的转换能区分普通键 / E0 扩展键 / E1 前缀键三种情况interception.rs这是它相比 LLHook 默认模式的显著优势——更贴近物理键盘的真实事件流。五、输出日志解读5.1 LLHook 模式默认模式下每按下一枚按键终端会打印一行形如INFO 0, WM_KEYDOWN(256), false, InputEvent { code: 65, up: false } INFO 0, WM_KEYUP(260), false, InputEvent { code: 65, up: true }四个字段依次为对应 llhook.rs字段含义code钩子回调的第一个参数当前为 0wparamWindows 消息类型如WM_KEYDOWN、WM_KEYUP帮助区分按下/抬起is_injected是否由程序注入LLKHF_INJECTED排查输入源时很有用InputEvent { code, up }解析出的按键码默认取vkCodewiniov2下为扫描码转换结果与抬起标志5.2 Interception 模式启用interception_driver后输出形如got stroke Keyboard { code: LeftShift, state: 0x2, information: 0 }: num: 42num是OsCode::try_from(stroke)成功后as_u16()得到的按键码数值若转换失败会打印unknown mapping! please file a bug containing these logs源码注释明确要求遇到未知映射时请把包含这些日志的完整输出提交为 buginterception.rs这正是该工具服务于补齐 kanata 映射表的闭环环节。六、源码级映射表解析interception.rs中实现了全量的扫描码 状态 → OsCode映射理解它有助于你读懂未知按键属于哪一类6.1 基础扫描码无 E0/E1 前缀覆盖标准键盘的主键区字母、数字、F1–F24、Esc、Tab、Enter、Backspace、空格、方向键、Print Screen、NumLock/ScrollLock、小键盘 0–9 与四则运算、以及Int1左 Shift 与 Z 之间的按键即KEY_102ND、Katakana等interception.rs。6.2 E0/E1 扩展扫描码带 E0 前缀的扫描码映射到系统与媒体功能键interception.rs典型条目包括扫描码OsCode物理键0x10KEY_PREVIOUSSONG上一曲0x19KEY_NEXTSONG下一曲0x1CKEY_KPENTER小键盘回车0x1DKEY_RIGHTCTRL右 Ctrl0x20KEY_MUTE静音0x22KEY_PLAYPAUSE播放/暂停0x2E / 0x30KEY_VOLUMEDOWN / KEY_VOLUMEUP音量减/加0x35KEY_KPSLASH小键盘除号0x37KEY_PRINTPrint Screen0x38KEY_RIGHTALT右 Alt0x47/0x48/0x49KEY_HOME/UP/PAGEUP导航区0x4B/0x4DKEY_LEFT/RIGHT左右方向键0x4F/0x50/0x51KEY_END/DOWN/PAGEDOWN导航区0x52/0x53KEY_INSERT/DELETE插入/删除0x5B/0x5CKEY_LEFTMETA / KEY_RIGHTMETA左/右 Win 键0x69/0x6AKEY_FORWARD / KEY_BACK浏览器前进/后退源码中以注释形式保留了一批尚未实现的扫描码浏览器收藏、搜索、刷新、电源/休眠、启动邮件等均标记为KEY_TODO正是潜在的可扩展点。6.3 OEM 键位差异源码注释特别提醒Interception 的 OEM 扫描码与 LLHook 的 OEM VK 码并不对应同一组按键interception.rs相关扫描码0x5A–0x5F、0x71 等在注释中被禁用。这解释了为什么同一把键盘在不同采集后端下OEM 按键的日志码值可能不同——排查时务必先确认工具使用的后端。6.4 OsCode → Windows VK 码反向表OsCode::as_u16()提供从 OsCode 回写到 Windows 虚拟键码的反向映射interception.rs字母数字直接对应0x30–0x5A的 VK 码KEY_SEMICOLON→VK_OEM_1、KEY_MINUS→VK_OEM_MINUS、KEY_LEFTCTRL→VK_LCONTROL、媒体键→VK_VOLUME_*/VK_MEDIA_*、KEY_RO→0xC1、KEY_HENKAN→VK_CONVERT等。这张表与 kanata 主程序在 parser/src/keyswindows.rs、mappings.rs、mod.rs中维护的按键名→码值映射相互印证是理解kanata 的按键名在 Windows 上究竟对应什么码的权威参考。七、实战排查一枚未收录的按键并反哺 kanata结合工具与仓库源码推荐如下排查流程选择后端先在默认 LLHook 模式下运行windows_key_tester.exe按下目标按键记录vkCode与注入状态再在 Interception 模式--features interception_driver下重复一次取得扫描码与 E0/E1 状态对照映射表将扫描码对照上文 6.1/6.2 节表格若命中则该键在 kanata 中已存在对应 OsCode可直接在配置中使用按键名可查 cfg_samples/kanata.kbd 等示例确认未收录若日志出现unknown mapping! please file a bug containing these logs说明该按键尚未映射——这正是工具的核心使用场景提交反馈将两种后端下的完整日志连同键盘型号、布局ANSI/ISO/JIS一起提交 issue开发者可据此在interception.rs的映射表与 parser/src/keys 中补充映射Linux 对照同样的按键在 Linux 上可用evtest直接读出对应的KEY_*码与 Windows 日志中的 OsCode 数值比对可快速判断两端是否应映射为同一按键。八、常见问题与注意事项非 Windows 环境程序仅打印占位信息不执行任何采集逻辑属于预期行为钩子不生效LLHook 模式必须保持事件循环运行dispatch_thread_events若在无消息循环的环境如部分脚本宿主中运行钩子可能无法触发Interception 启动失败会抛出interception driver should init: have you completed the interception driver installation?请先完成驱动安装启动前请松开按键程序会先休眠 2 秒并要求不要按键以避免把启动瞬间的按键误录为事件该工具不影响系统输入无论 LLHook 还是 Interception事件都会被原样回传给操作系统可以放心在真实工作环境中排查。总结windows_key_tester是 kanata 生态中一块小而关键的测量仪器它以 evtest 为设计蓝本在 Windows 上提供 LLHook 与 Interception 两套采集后端将物理按键转译成 kanata 统一的 OsCode 并原样放行从而在不干扰正常输入的前提下暴露出尚未被收录的按键映射。无论是普通用户排查配置中不生效的按键还是开发者为其补充新键位映射本文介绍的构建方式、日志格式与源码级映射表都足以作为直接的操作手册与参考索引。【免费下载链接】kanataImprove keyboard comfort and usability with advanced customization项目地址: https://gitcode.com/GitHub_Trending/ka/kanata创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表