Поиск информации обо всех последовательных устройствах, подключенных через USB в С#
Мой проект требует обнаружения определенного устройства, когда он подключен к USB. Единственным способом, которым я могу идентифицировать это устройство, является его описание/имя устройства, а не com-порт. То, что я нашел для выполнения правильной функции, - это использование запроса WMI и проверка свойства name:
ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * from WIN32_SerialPort");
foreach (ManagementObject port in searcher.Get())
{
deviceName = (string)foundPort.GetPropertyValue("Name");
...
Сначала я тестировал это, подключив свой телефон, и запрос вернул телефон, найденный на COM3, как и ожидалось. Затем я подключил другое устройство (USB-последовательный преобразователь, который более близко напоминает устройство, для которого мне нужен этот проект), и запрос просто его не нашел. Он находит телефон только. Однако это устройство отображается на порту COM4 в диспетчере устройств. Еще больше назло класс SerialPort нашел оба устройства, но он не предоставляет информацию, необходимую мне для идентификации устройства:
string[] tempPorts = SerialPort.GetPortNames();
Я прочитал множество потоков на SO и в других местах и не могу найти удовлетворительное решение. Может кто-то прояснить, почему запрос WIN32_SerialPort не находит другое устройство? Разве это не считается серийным портом win32 по какой-то причине?
И, может кто-нибудь, пожалуйста, укажите мне направление решения этой проблемы?
Ответы
Ответ 1
Как перечислить все последовательные порты:
Существует несколько "Классы настройки системных устройств", доступные для поставщиков оборудования. Правильно написанные драйверы для COM-Ports
должны использовать Ports (COM & LPT ports)
-class (guid: 4d36e978-e325-11ce-bfc1-08002be10318
). Вероятно, этот класс также используется диспетчером устройств.
Таким образом, вы можете использовать следующий запрос, чтобы перечислить каждый последовательный порт, который вы также видите в devicemanager:
ManagementObjectSearcher searcher = new ManagementObjectSearcher(
"root\\CIMV2",
"SELECT * FROM Win32_PnPEntity WHERE ClassGuid=\"{4d36e978-e325-11ce-bfc1-08002be10318}\""
);
foreach (ManagementObject queryObj in searcher.Get())
{
// do what you like with the Win32_PnpEntity
}
Смотрите это подробное описание Win32_PnPEntity -класс. У вас должно быть все необходимое для идентификации вашего устройства.
Для определения номера порта я исследую свойство name и извлекаю его. До сих пор это работает нормально, но я не знаю, будет ли номер порта гарантированно включен в имя. До сих пор я не нашел устройства последовательного порта, у которого нет номера порта, включенного в это имя.
Вышеприведенный запрос находит каждое устройство последовательного порта, независимо от того, является ли это bluetooth SPP, FTDI-чипом, портом на материнской плате, картой расширения или виртуальным последовательным портом, созданным каким-либо драйвером модема (то есть Globetrotter GTM66xxW).
Чтобы определить тип подключения (bluetooth, usb и т.д.), вы можете изучить deviceid (посмотрите на первую часть deviceid). Там вы также можете извлечь адрес bt-mac (будьте осторожны: deviceid выглядит по-разному, по крайней мере, в Windows 7 и Windows XP).
Относительно того, почему некоторые устройства не указаны в Win32_SerialPort:
Я подозреваю, что это зависит от реализации драйвера, так как у меня есть некоторые USB-устройства, которые перечисляют их порты, а некоторые нет.
Ответ 2
Я думаю, что вижу, что вы пытаетесь сделать, посмотрите на этот код, сделанный с помощью WMICodeCreator (ссылка на WMICodeCreator http://www.microsoft.com/en-us/download/details.aspx?id=8572)
из этой статьи http://www.codeproject.com/Articles/32330/A-Useful-WMI-Tool-How-To-Find-USB-to-Serial-Adapto
//Below is code pasted from WMICodeCreator
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSSerial_PortName");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("MSSerial_PortName instance");
Console.WriteLine("-----------------------------------");
Console.WriteLine("InstanceName: {0}", queryObj["InstanceName"]);
Console.WriteLine("-----------------------------------");
Console.WriteLine("MSSerial_PortName instance");
Console.WriteLine("-----------------------------------");
Console.WriteLine("PortName: {0}", queryObj["PortName"]);
//If the serial port instance name contains USB
//it must be a USB to serial device
if (queryObj["InstanceName"].ToString().Contains("USB"))
{
Console.WriteLine(queryObj["PortName"] + "
is a USB to SERIAL adapter/converter");
}
}
}
catch (ManagementException e)
{
MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}