Search code examples
c#.netusbwmiwmic

Is it possible to get PC's # of physical USB ports?


I'm trying to get number of physical USB ports of PC for different Windows operating systems. To start with it seemed like an easy task but now I'm getting desperate.

Maybe this question is not even valid since I don't know how USB ports are treated on hardware level.

I thought using WMI(C) and ManagementObjectSearcher would be the right path to take and it returned right values... on certain operating systems. Or that's what I thought.

For example, I tried the following:

// >wmic path win32_usbhub get name

private const string UsbProperty = "Name";
private const string UsbPath = "Win32_USBHub";
private const string UsbPortName = "USB ROOT HUB";

...

// Get USB Ports
public IEnumerable<string> GetUsbPorts()
{
    // All from Win32_USBHub where name contains USB ROOT HUB
    return GetManagementObjectValues(UsbProperty, UsbPath).Where(name => 
        CultureInfo.CurrentCulture.CompareInfo.IndexOf(
            name, UsbPortName, CompareOptions.IgnoreCase) >= 0);
}

.

// Query
private static IEnumerable<string> GetManagementObjectValues(
    string properties, string path, Func<object, string> formatter = null)
{
    var values = new List<string>();
    string query = string.Format("SELECT {0} FROM {1}", properties, path);
    var search = new ManagementObjectSearcher(query);

    try
    {
        foreach (ManagementObject item in search.Get())
        {
            string value = string.Empty;
            foreach (string property in properties.Split(',')
                .Select(prop => prop.Trim()))
            {
                if (item[property] == null)
                    continue;

                if (value.Length > 0)
                    value += " ";

                if (formatter != null)
                    value += formatter(item[properties]);
                value += item[property].ToString();
            }
            values.Add(value.TrimEnd());
        }
    }
    catch (Exception e)
    {
        if (e is ManagementException)
            Logger.Warn(string.Format(
                "Can't extract {0} properties of {1}", properties, path), e);
        else
            Logger.Error(e);
    }

    return values.Count >= 1 ? values : new List<string> { DefaultValue };
}

This seemed to get me the right amount on Windows8 but on WindowsXP it was totally off.

Next, I tried (for example) the following. I noticed that on Win8 I have USB<number> as ExternalReferenceDesignator but on WinXP, there's plain USB as InternalReferenceDesignator and external is empty.

For XP this seemed to work just fine but then again on Win8 amount of ports was six (6). Actual port count is 3 and with docking station station seven (7).

// >wmic path Win32_PortConnector get ExternalReferenceDesignator,InternalReferenceDesignator

private const string UsbPortName = "USB";     
private const string PortProperties = 
    "ExternalReferenceDesignator, InternalReferenceDesignator";
private const string PortPath = @"Win32_PortConnector";

...

public IEnumerable<string> GetEthernetPorts()
{
    // All where external includes USB or internal equals USB
    return GetManagementObjectValues(PortProperties, PortPath).Where(name => 
        CultureInfo.CurrentCulture.CompareInfo.IndexOf(
            name, UsbPortName, CompareOptions.IgnoreCase) >= 0 ||
        string.Compare(name, UsbPortName, StringComparison.OrdinalIgnoreCase) == 0);
}    

So is it even possible or am I just looking from the wrong place?


Solution

  • And to answer my own question: No, it's not possible.

    WMIC query results for Win32_USBController (or some related path) might seem right but you can't draw any conclusions from them. Information about connectors aren't stored on the baseboard or any other location either.

    For example an old Dell Latitude D830 with Windows XP SP3 has three (3) physical connectors but WMIC and USBView.exe shows results below:

    C:\>wmic path win32_usbcontroller get caption
    Caption
    Intel(R) ICH8 Family USB Universal Host Controller - 2834
    Intel(R) ICH8 Family USB Universal Host Controller - 2835
    Intel(R) ICH8 Family USB2 Enhanced Host Controller - 283A
    Intel(R) ICH8 Family USB Universal Host Controller - 2830
    Intel(R) ICH8 Family USB Universal Host Controller - 2831
    Intel(R) ICH8 Family USB Universal Host Controller - 2832
    Intel(R) ICH8 Family USB2 Enhanced Host Controller - 2836
    

    imgur