Можно ли получить на ПК количество физических USB-портов?

Я пытаюсь получить количество физических USB-портов ПК для разных операционных систем Windows. Начать с этого казалось легкой задачей, но теперь я впадаю в отчаяние.

Может быть, этот вопрос даже не действителен, так как я не знаю, как обрабатываются порты USB на аппаратном уровне.

Я думал, используя WMI(C) а также ManagementObjectSearcher будет правильным путем, и он вернет правильные значения... в определенных операционных системах. Или это то, что я думал.

Например, я попробовал следующее:

// >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 };
}

Похоже, что это правильно для Windows8, но на WindowsXP оно было полностью отключено.

Далее я попробовал (например) следующее. Я заметил, что на Win8 у меня есть USB<number> как ExternalReferenceDesignator но на WinXP есть простой USB как InternalReferenceDesignator а внешний пуст.

Для XP это работало нормально, но опять же на Win8 количество портов было шесть (6). Фактическое количество портов - 3, а с док-станцией - семь (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);
}    

Так это вообще возможно или я просто смотрю не с того места?

2 ответа

Решение

И ответить на мой собственный вопрос: нет, это невозможно.

Результаты запроса WMIC для Win32_USBController (или некоторый связанный путь) может показаться правильным, но вы не можете сделать из них никаких выводов. Информация о разъемах не хранится ни на плате, ни в каком-либо другом месте.

Например, старый Dell Latitude D830 с Windows XP SP3 имеет три (3) физических разъема, но WMIC и USBView.exe показывает результаты ниже:

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

Я знаю, что прошло много времени с тех пор, как был задан вопрос, но я просто работал над деревом USB-портов для какого-то приложения поддержки. Первоначально я пытался использовать Win32..., поскольку он не предназначен для использования в качестве источника информации для перестроения дерева устройств, ответ на этот пост объясняет некоторые возможности (Получить список подключенных USB- устройств) . Я играл с ним, но он мне не понравился. UsbView сам по себе тоже не вариант (отсутствие навыков в C). К счастью, я нашел . Он предоставляет вам дерево USB-устройств, вам просто нужно понять, как его читать. Не физический порт USBНа этом изображении показан порт, на котором четко указано, что его невозможно использовать. В дополнение к этому параметру есть «Имя символической ссылки Companion Hub», по моему опыту, оно должно присутствовать на действующем USB-порту. Насчет нескольких контроллеров и даже нескольких портов в одном контроллере, удовлетворяющих моему предыдущему утверждению, есть объяснение. Несколько портов для одного физического порта, в моем случае порты 1 и 13 совпадают. Если устройство 1.1 или 2.0, оно будет отображаться под портом 1, а если оно поддерживает 3.0, оно будет отображаться под портом 13. И то же самое касается двух контроллеров, у них нет на 100% одинаковой структуры, но как только вы удалите ненужные данные и объединить оставшиеся данные (не обязательно все), результатом будет дерево портов USB. Я не могу гарантировать, что все утверждения верны, но это мой текущий опыт, и я могу обновить этот пост. Если нет, не стесняйтесь, напишите мне, если у вас есть вопросы. Кстати. NativeUsbLibNativeUsbLib по умолчанию не предоставляет данные для портов, в которых нет устройства (подключенного). Чтобы исправить это, закомментируйте строки в DeviceFactory, которые проверяют наличие устройства (строка 35). Надеюсь, это кому-то поможет, и извините за мою орфографию, я уверен, что где-то напутал...

Другие вопросы по тегам