Electron应用中如何通过node-hid以非独占模式跨平台打开游戏手柄设备?
Electron应用中如何通过node-hid以非独占模式跨平台打开游戏手柄设备?
嗨,我之前刚好遇到过一模一样的需求,折腾了好一阵子才搞定,现在把具体的实现方法和注意事项分享给你:
首先你说的没错,node-hid底层依赖的hidapi确实支持跨平台的非独占访问,但node-hid默认是用独占模式打开设备的,所以我们需要在打开设备的时候手动传入配置参数来切换模式,不同平台的参数略有区别:
核心实现代码
先给你看跨平台的通用代码,里面已经包含了各平台的非独占配置:
const HID = require('node-hid'); // 第一步:找到你的目标游戏手柄设备 // 这里需要替换成你手柄的vendorId和productId,比如Xbox手柄是0x045e和0x028e const targetVendorId = 0x045e; const targetProductId = 0x028e; const gamepad = HID.devices().find(dev => dev.vendorId === targetVendorId && dev.productId === targetProductId ); if (!gamepad) { console.error("没找到目标游戏手柄设备"); return; } // 第二步:配置跨平台的非独占选项 const openOptions = { // Windows平台:开启共享模式,允许其他进程访问设备 shared: true, // macOS平台:开启非独占模式 nonExclusive: true }; // 第三步:以非独占模式打开设备 try { const hidDevice = new HID.HID(gamepad.path, openOptions); console.log("成功以非独占模式打开游戏手柄!"); // 监听手柄数据(如果需要的话) hidDevice.on('data', (data) => { console.log("收到手柄输入数据:", data); }); hidDevice.on('error', (err) => { console.error("设备出错:", err); }); } catch (err) { console.error("打开设备失败:", err); }
各平台额外注意事项
- Windows平台:只要代码里设置了
shared: true,基本上就能正常以共享模式打开设备,其他游戏或软件可以同时访问手柄。 - macOS平台:确保设置了
nonExclusive: true,这个参数会让hidapi跳过系统的独占锁,允许多个进程使用同一个手柄。 - Linux平台:默认就是非独占模式,但需要注意权限问题。可以通过添加udev规则来给手柄设备赋予通用权限:
- 创建文件
/etc/udev/rules.d/99-gamepad-permissions.rules - 写入内容:
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="你的手柄vendorId", ATTRS{idProduct}=="你的手柄productId", MODE="0666" - 重启udev服务:
sudo udevadm control --reload-rules && sudo udevadm trigger,然后重新插拔手柄
- 创建文件
验证是否生效
打开你的Electron应用后,再启动其他依赖手柄的软件(比如Steam游戏、手柄测试工具),如果两边都能正常识别和使用手柄,就说明非独占模式已经成功开启了。
其他小提示
- 确保你安装的是最新版的node-hid,旧版本可能不支持这些配置参数:
npm install node-hid@latest - 因为node-hid是原生模块,和Electron版本可能存在兼容性问题,安装后记得用electron-rebuild重新构建:
npx electron-rebuild
备注:内容来源于stack exchange,提问作者sasidhar




