6

我有两个 USB 设备 ID,例如USB\VID_E4F1&PID_0661\00000115FA9CE7750000000000000000USB\VID_E4F1&PID_0661&MI_00\7&B5A5DDF&0&0000

如何验证设备 #2 是设备 #1 的直接子设备(实际上它们是同一 USB 复合设备的不同部分)?

在现实生活场景中,它们中的许多将连接到同一个 USB 控制器。此外,它们可能是相同的制造商和型号。这就是为什么我无法验证 VID、PID 并使用Win32_USBControllerDeviceWMI 查询来验证它们是否插入同一个 USB 控制器 - 我需要以某种方式验证父子关系,而不仅仅是它们插入同一个控制器的事实。

如果重要的话,我只需要支持 Windows 8+。

4

3 回答 3

6

PnP 配置管理器 API是您的朋友:

于 2014-09-24T20:23:01.460 回答
4

如果您能够使用新的 WinRT API,您应该查看PnpObject类和命名空间。

这是一个代码示例:

var propertiesToQuery = new List<string>() { 
    "System.ItemNameDisplay",
    "System.Devices.DeviceInstanceId",
    "System.Devices.Parent",
    "System.Devices.LocationPaths",
    "System.Devices.Children"
};

var id1 = @"USB\VID_E4F1&PID_0661\00000115FA9CE7750000000000000000";

var device1 = await PnpObject.FindAllAsync(PnpObjectType.Device, 
                                            propertiesToQuery, 
                                            "System.Devices.DeviceInstanceId:=\"" + id1 + "\"");

var id2 = @"USB\VID_E4F1&PID_0661&MI_00\7&B5A5DDF&0&0000";

var device2 = await PnpObject.FindAllAsync(PnpObjectType.Device, 
                                            propertiesToQuery, 
                                            "System.Devices.DeviceInstanceId:=\"" + id2 + "\"");


var parent1 = device1.Properties["System.Devices.Parent"] as string;
var parent2 = device2.Properties["System.Devices.Parent"] as string;

if (parent1 && parent1 == id2)
{
    WriteLine("Device 2 is parent of device 1");
}

if (parent2 && parent2 == id1)
{
    WriteLine("Device 11 is parent of device 2");
}

var child_ids = device1.Properties["System.Devices.Children"] as string[];

if (child_ids != null){
    foreach (var id in child_ids)
    {
        if (id == id2){
            WriteLine("Device 2 is child of device 1")
        }
    }
}

 child_ids = device2.Properties["System.Devices.Children"] as string[];

if (child_ids != null){
    foreach (var id in child_ids)
    {
        if (id == id1){
            WriteLine("Device 1 is child of device 2")
        }
    }
}

如果这还不够,您可以尝试向上或向下父/子路径。

您还可以查看System.Devices.LocationPaths属性(它是一个字符串数组)并测试一个是否是另一个的前缀。

于 2017-06-15T08:27:14.123 回答
-1

扩展 Harry Johnston 的出色答案:

调用CM_Locate_DevNode后,您可以通过单个函数调用获取父设备实例 ID:

#include <propkey.h>

// Get the Parent Device Property
DEVPROPTYPE propType;
wchar_t propBuf[MAX_DEVICE_ID_LEN] = {};
ULONG propBufSize = sizeof(propBuf);
CONFIGRET cres = CM_Get_DevNode_Property(devInst, (DEVPROPKEY*)&PKEY_Devices_Parent, &propType, (BYTE*)propBuf, &propBufSize, 0);
if (cres == CR_SUCCESS) {
    // propBuf now contains the Parent System Device ID!
}
于 2019-07-03T13:36:47.417 回答