UWP开发读取HidDevice耳机固件版本遇报错求助
解决UWP HID设备读取固件版本的两个常见错误
你遇到的两个错误都是HID设备通信中典型的匹配性问题,咱们逐个拆解排查:
错误1:"Value does not fall within the expected range"(在outReport.Data = dataWriter.DetachBuffer();)
这个错误的核心是你设置的缓冲区大小和HID设备输出报告的要求不匹配。HID设备的每个报告都有固定的字节长度,必须严格对齐才能正常发送。
排查与修正:
先确认设备的输出报告大小
在创建输出报告后,先获取设备要求的标准长度,避免盲目用64字节:var hidDevice = DeviceManagerEventHandler.Current.HidDevice; int expectedOutputSize = hidDevice.OutputReportByteLength; Debug.WriteLine($"设备要求的输出报告大小:{expectedOutputSize}");如果这个值不是64,你的
queryVersion()返回的数组长度就需要调整为对应大小。正确处理报告ID
你的cmd[0] = 0x0B应该是报告ID,但很多HID设备的报告ID是单独字段,不算在Data缓冲区的长度里。正确的做法是通过CreateOutputReport指定报告ID,Data里只放命令内容:// 直接指定报告ID,不用把ID塞进Data数组 HidOutputReport outReport = hidDevice.CreateOutputReport(0x0B); // 按设备要求的大小创建命令缓冲区 byte[] buffer = new byte[expectedOutputSize]; buffer[0] = 0x11; // 这里只放命令的有效内容,后续字节留0即可确保缓冲区完全匹配
写入DataWriter后,检查缓冲区长度是否和设备要求一致:DataWriter dataWriter = new DataWriter(); dataWriter.WriteBytes(buffer); IBuffer outputBuffer = dataWriter.DetachBuffer(); if (outputBuffer.Length != expectedOutputSize) { rootPage.NotifyUser("缓冲区大小与设备要求不匹配", NotifyType.ErrorMessage); return; } outReport.Data = outputBuffer;
错误2:"A device attached to the system is not functioning"(在GetInputReportAsync())
这个错误大多是因为前面的输出报告发送失败,设备没有响应,或者读取方式不符合设备要求。
排查与修正:
先确保输出报告发送成功
在发送后检查返回状态,确认命令已正常送达设备:var sendResult = await hidDevice.SendOutputReportAsync(outReport); if (sendResult.Status != HidDeviceStatus.Success) { rootPage.NotifyUser($"发送报告失败:{sendResult.Status}", NotifyType.ErrorMessage); return; }指定输入报告ID读取
很多设备需要指定报告ID才能获取对应响应,不要用无参数的GetInputReportAsync():// 假设设备返回的固件版本报告ID也是0x0B,需根据设备文档调整 HidInputReport inReport = await hidDevice.GetInputReportAsync(0x0B);检查设备权限与占用情况
- 确认
Package.appxmanifest中已正确声明HID设备权限,替换成你的设备VID/PID和Usage信息:<DeviceCapability Name="humaninterfacedevice"> <Device Id="vidpid:XXXX XXXX"> <Function Type="usage:FF00 0001" /> </Device> </DeviceCapability> - 关闭可能占用耳机的其他进程(比如系统音频服务、其他耳机管理软件),避免设备被锁定。
- 确认
额外建议
- 获取设备HID描述符:用HID调试工具(比如Windows自带的HidExplorer)查看设备的报告描述符,明确输入/输出报告的大小、ID、协议细节,这是解决HID问题的核心依据。
- 遵循厂商协议:不同耳机的固件查询命令格式可能有差异,比如字节顺序、校验位等,务必对照设备的开发文档调整
queryVersion()的内容。 - 优化异步方法:把
async void改成async Task,避免异步调用中的潜在问题:public async Task ReadFirmwareVersion() { // 原有逻辑不变 }
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

