如何使用C# ManagementObject获取USB设备的父子关系
获取USB复合设备与子设备的父子关系(C# WMI实现)
Win32_PnPEntity本身没有直接暴露父设备关联属性,要获取设备管理器中显示的USB复合设备(父)与扬声器、麦克风、COM端口等子设备的层级关系,需要结合WMI关联类和更精准的设备类来实现,核心思路是通过Win32_DeviceParent关联类建立父设备与子设备的映射,或者直接查询Win32_USBCompositeDevice的关联子设备。
方法一:从USB复合设备出发,查询关联子设备
直接定位USB复合设备类Win32_USBCompositeDevice,再通过Win32_DeviceParent关联类获取其下属的所有子设备:
using System; using System.Management; class DeviceHierarchy { static void Main() { // 获取所有USB复合设备 var compositeDeviceQuery = new ManagementObjectSearcher("SELECT * FROM Win32_USBCompositeDevice"); foreach (ManagementObject compositeDevice in compositeDeviceQuery.Get()) { string deviceName = compositeDevice["Name"]?.ToString() ?? "未知设备"; string pnpId = compositeDevice["PNPDeviceID"]?.ToString() ?? "无PNP ID"; Console.WriteLine($"=== USB复合设备: {deviceName} (PNP ID: {pnpId}) ==="); // 查询该复合设备的子设备 string childQuery = $"ASSOCIATORS OF {{Win32_USBCompositeDevice.DeviceID='{compositeDevice["DeviceID"]}'}} WHERE AssocClass=Win32_DeviceParent"; var childDeviceSearcher = new ManagementObjectSearcher(childQuery); foreach (ManagementObject childDevice in childDeviceSearcher.Get()) { string childName = childDevice["Name"]?.ToString() ?? "未知子设备"; string childDesc = childDevice["Description"]?.ToString() ?? "无描述"; Console.WriteLine($" 子设备: {childName} - {childDesc}"); } Console.WriteLine(); } } }
方法二:从子设备出发,反向查找父复合设备
如果已知子设备类型(如扬声器、COM端口),可以先通过Win32_PnPEntity定位子设备,再通过关联类反向查询父复合设备:
using System; using System.Management; class DeviceParentLookup { static void Main() { // 定位目标子设备(扬声器、麦克风、COM端口) var targetDevicesQuery = new ManagementObjectSearcher( "SELECT * FROM Win32_PnPEntity WHERE Description LIKE '%扬声器%' OR Description LIKE '%麦克风%' OR Description LIKE '%COM%'"); foreach (ManagementObject childDevice in targetDevicesQuery.Get()) { string childName = childDevice["Name"]?.ToString() ?? "未知设备"; Console.WriteLine($"子设备: {childName}"); // 查询父设备,过滤出USB复合设备 string parentQuery = $"ASSOCIATORS OF {{Win32_PnPEntity.DeviceID='{childDevice["DeviceID"]}'}} WHERE AssocClass=Win32_DeviceParent Role=Parent"; var parentDeviceSearcher = new ManagementObjectSearcher(parentQuery); foreach (ManagementObject parentDevice in parentDeviceSearcher.Get()) { if (parentDevice.ClassPath.ClassName.Equals("Win32_USBCompositeDevice", StringComparison.OrdinalIgnoreCase)) { string parentName = parentDevice["Name"]?.ToString() ?? "未知复合设备"; string parentPnpId = parentDevice["PNPDeviceID"]?.ToString() ?? "无PNP ID"; Console.WriteLine($" 父USB复合设备: {parentName} (PNP ID: {parentPnpId})"); } } Console.WriteLine(); } } }
关键注意事项
- 权限要求:运行程序需要管理员权限,否则可能无法访问部分设备的WMI属性或关联关系。
- 设备ID匹配:WMI中的
DeviceID是内部标识,而PNPDeviceID是系统级的设备实例ID,与设备管理器中显示的ID一致,可用于跨类匹配设备。 - 递归查询:部分复杂设备可能存在多层父子关系,若需要完整层级,可在获取子设备后继续递归查询其子设备的关联关系。
- 类选择:
Win32_USBCompositeDevice是专门标识USB复合设备的类,比通用的Win32_PnPEntity更精准,避免误匹配其他USB设备。
内容的提问来源于stack exchange,提问作者Rudi Gerrits
相关产品推荐
相关产品推荐

