C# Find specific slot no of the USB Hub(10 slots)

2020-05-06 21:26发布

问题:

C# I have a USB Hub of 10 USB slots connected to my USB Port. I want to get the USB device connected to the specific port.
Example: Two USB's are connected at Slot 3 and Slot 7. So, I want a list which will show Slot 3 and Slot 7 have USB and rest slot are empty. I have tried using WMI Query Win32_USBHub. But here I am only getting 6 device id's and not 10. I am differentiating the ports using common VID for the Device ID. But still even after getting the USB's connected to the specific port. I want to get their corresponding slot in which they are connected to USBHub. I am not able to identify the slot in which the USB is connected and where the slot is empty.

ManagementObjectCollection collection;
var searcher = new ManagementObjectSearcher(@"Select * From Win32_USBHub");
collection = searcher.Get();

回答1:

I would try to extract location information from the USB device (the same as in device manager)... I do not code in C# nor WMI but you should be able to obtain this kind of info with setupapi.h which is part of winapi (I think) I do it like this in C++/VCL:

#include <setupapi.h>
bool USBinfo()
    {
    int i,n;
    AnsiString s,txt="";
    DWORD dwSize,dwPropertyRegDataType;
    HDEVINFO hDevInfo;
    SP_DEVINFO_DATA DeviceInfoData;
    TCHAR szDesc[1024];

    // List all connected USB devices
    hDevInfo = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
    if (hDevInfo == INVALID_HANDLE_VALUE) return false;
    for (i=0;;i++)
        {
        DeviceInfoData.cbSize = sizeof(DeviceInfoData);
        if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData)) break;
        SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC,&dwPropertyRegDataType, (BYTE*)szDesc,sizeof(szDesc),&dwSize);
        s=szDesc; n=48; while (s.Length()<n) s+=" "; if (s.Length()>n) s=s.SubString(1,n); txt+=s+" "; // this just set constant string size to allign the columns to n chars
        SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_HARDWAREID,&dwPropertyRegDataType, (BYTE*)szDesc,sizeof(szDesc),&dwSize);
        s=szDesc; if (s=="USB\\VID_????&PID_????REV_????")
            {
            // here you can do custom stuff for specific VID,PID just change the ???? in above line to your specific VID,PID,REV
            }
        s=szDesc; n=64; while (s.Length()<n) s+=" "; if (s.Length()>n) s=s.SubString(1,n); txt+=s+" ";
        SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_LOCATION_INFORMATION,&dwPropertyRegDataType, (BYTE*)szDesc,sizeof(szDesc),&dwSize);
        s=szDesc; n=64; while (s.Length()<n) s+=" "; if (s.Length()>n) s=s.SubString(1,n); txt+=s+" ";
        txt+="\r\n";
        }
    Main->mm_log->Lines->Add(txt); // this just output txt string to memo
    return true;
    }

Here output on my machine:

USB Root Hub                                     USB\ROOT_HUB&VID1022&PID7807&REV0011                             USB\ROOT_HUB&VID1022&PID7807&REV0011                             
USB Root Hub                                     USB\ROOT_HUB&VID1022&PID7807&REV0011                             USB\ROOT_HUB&VID1022&PID7807&REV0011                             
USB Root Hub                                     USB\ROOT_HUB&VID1022&PID7809&REV0011                             USB\ROOT_HUB&VID1022&PID7809&REV0011                             
USB Root Hub                                     USB\ROOT_HUB20&VID1022&PID7808&REV0011                           USB\ROOT_HUB20&VID1022&PID7808&REV0011                           
USB Root Hub                                     USB\ROOT_HUB20&VID1022&PID7808&REV0011                           USB\ROOT_HUB20&VID1022&PID7808&REV0011                           
USB Composite Device                             USB\VID_048D&PID_9006&REV_0200                                   Port_#0001.Hub_#0004                                             
IT9135 BDA Device                                USB\VID_048D&PID_9006&REV_0200&MI_00                             0000.0013.0002.001.000.000.000.000.000                           
USB Input Device                                 USB\VID_048D&PID_9006&REV_0200&MI_01                             0000.0013.0002.001.000.000.000.000.000                           
Canon LiDE 30                                    USB\VID_04A9&PID_220E&REV_0100                                   Port_#0005.Hub_#0001                                             
American Power Conversion USB UPS                USB\VID_051D&PID_0002&REV_0106                                   Port_#0001.Hub_#0001                                             
USB Input Device                                 USB\Vid_093A&Pid_2510&Rev_0100                                   USB Optical Mouse                                                
USB Input Device                                 USB\VID_413C&PID_2107&REV_0115                                   Port_#0002.Hub_#0001                                             

As you can see the last column (3th) holds the info you want. Look inside setupapi.h for all the SPDRP_ defines you can use ... The only thing used from VCL is AnsiString so change it to any string type you have at your disposal.

This is not restricted to USB. If you want all the devices then change TEXT("USB") search parameter to NULL

hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);


标签: c# .net wmi