我有两个USB设备ID,例如USB\VID_E4F1&PID_0661\00000115FA9CE7750000000000000000
和USB\VID_E4F1&PID_0661&MI_00\7&B5A5DDF&0&0000
如何验证设备#2是设备#1的直接子设备(实际上它们是同一USB复合设备的不同部分)?
在现实生活中,它们中的许多都连接到同一个USB控制器。而且,它们可能是同一个制造商和型号。这就是为什么我无法验证VID,PID并使用Win32_USBControllerDevice
WMI查询来验证它们是否已插入同一USB控制器 - 我需要以某种方式验证父子关系,而不仅仅是事实上他们已经插入同一个控制器。
如果重要,我只需要支持Windows 8 +。
答案 0 :(得分:3)
PnP Configuration Manager API是你的朋友:
CM_Locate_DevNode会根据设备ID打开设备句柄;
CM_Get_Parent找到父设备;
CM_Get_Device_ID_Size和CM_Get_Device_ID获取设备句柄并返回设备ID。
答案 1 :(得分:2)
如果您能够使用新的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
属性(这是一个字符串数组)并测试一个是否是另一个的前缀。
答案 2 :(得分:0)
扩展了哈里·约翰斯顿的绝妙答案:
调用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!
}