You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP中获取USB字符串描述符及识别同一物理设备双接口方法

解决UWP中关联同一USB设备的HID与WinUSB接口及获取字符串描述符问题

我之前在做UWP和多接口USB设备通信时也踩过一模一样的坑,咱们一步步来搞定这两个核心需求:

一、关联同一物理设备的HID和WinUSB接口

核心思路是利用容器ID(Container ID)——这是Windows给每个物理USB设备分配的唯一标识,同一设备的所有接口(不管是HID还是WinUSB)都会共享这个ID。具体操作如下:

1. 获取HID设备的Container ID

假设你已经成功打开了HidDevice实例,通过它的设备信息ID获取对应的DeviceInformation对象,再读取System.Devices.ContainerId属性:

// 已初始化的HidDevice实例
HidDevice hidDevice = ...;

var hidDeviceInfo = await DeviceInformation.CreateFromIdAsync(
    hidDevice.DeviceInformation.Id,
    new[] { "System.Devices.ContainerId" }); // 指定只获取需要的属性,提升性能

Guid hidContainerId = Guid.Parse(hidDeviceInfo.Properties["System.Devices.ContainerId"].ToString());

2. 获取WinUSB设备的Container ID

对已打开的UsbDevice实例,用同样的方式获取Container ID:

// 已初始化的UsbDevice实例
UsbDevice usbDevice = ...;

var usbDeviceInfo = await DeviceInformation.CreateFromIdAsync(
    usbDevice.DeviceInformation.Id,
    new[] { "System.Devices.ContainerId" });

Guid usbContainerId = Guid.Parse(usbDeviceInfo.Properties["System.Devices.ContainerId"].ToString());

3. 判断是否为同一物理设备

只要比较两个Container ID是否相等即可:

if (hidContainerId == usbContainerId)
{
    // 确认是同一物理设备
}

小提示:也可以用设备实例路径判断,但Container ID更可靠——即使设备插拔、驱动更新,Container ID通常保持不变,而设备实例路径可能会变化。

二、在UWP中获取USB字符串描述符

根据设备接口类型,有两种常用方法:

方法1:通过WinUSB接口获取(推荐,支持所有字符串描述符)

UsbDevice允许直接发送标准USB控制请求读取字符串描述符。比如读取产品字符串(索引对应设备描述符里的ProductStringIndex):

// 构造标准控制请求:获取字符串描述符
var controlSetup = new UsbControlSetupPacket(
    UsbControlDirection.In,                // 数据输入(从设备到主机)
    UsbControlRequestType.Standard,         // 标准请求类型
    (byte)UsbStandardRequest.GetDescriptor, // 请求码:获取描述符
    (ushort)((1 << 8) | usbDevice.DeviceDescriptor.ProductStringIndex), // 高字节=描述符类型(1=字符串),低字节=字符串索引
    0x0409); // 语言ID,0x0409代表英文(可根据设备支持的语言调整)

// 发送控制传输,缓冲区大小设为256(足够容纳大部分USB字符串)
var transferResult = await usbDevice.SendControlInTransferAsync(controlSetup, 256);

if (transferResult.Status == UsbTransferStatus.Completed)
{
    // 字符串描述符是Unicode编码,转换为C#字符串
    string productString = Encoding.Unicode.GetString(transferResult.Data).TrimEnd('\0');
}

如果要读取厂商字符串,把ProductStringIndex换成ManufacturerStringIndex即可;自定义字符串则替换为对应的索引值。

方法2:通过DeviceInformation读取常用字符串(HID设备适用)

HID API没有直接提供读取字符串描述符的方法,但可以通过DeviceInformation的内置属性获取厂商、产品名称等常用字符串——这些值就是从USB字符串描述符读取的:

var hidDeviceInfo = await DeviceInformation.CreateFromIdAsync(
    hidDevice.DeviceInformation.Id,
    new[] { "System.Devices.DeviceManufacturer", "System.Devices.DeviceProductName" });

string manufacturer = hidDeviceInfo.Properties["System.Devices.DeviceManufacturer"].ToString();
string productName = hidDeviceInfo.Properties["System.Devices.DeviceProductName"].ToString();

注意:这种方法只能获取系统预定义的几个字符串,无法读取自定义描述符,若需要自定义字符串,还是得通过WinUSB接口获取。

额外注意事项

  • 确保UWP应用在Package.appxmanifest中声明了对应设备功能:HID设备需声明DeviceCapability为humaninterfacedevice,WinUSB设备需声明usb功能并指定对应的VID/PID。
  • 读取字符串描述符时,语言ID要和设备支持的一致,大部分设备支持0x0409(英文),若需其他语言,可先读取语言ID列表(字符串描述符索引0)获取设备支持的语言。

内容的提问来源于stack exchange,提问作者Damiendra Buwaneka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:06:38