Как узнать номер COM-порта Bluetooth-устройства в С#?
Моя компания разработала устройство, которое взаимодействует с ПК через Bluetooth с помощью виртуального COM-порта.
Теперь нам нужно сначала подключить устройство с ПК (MS Windows OS), а затем ввести его номер COM-порта вручную в наше приложение (я уверен, что 95% пользователей потерпят неудачу на этих taks).
Поэтому я хотел бы, чтобы мое приложение представило пользователю список парных Bluetooth-устройств (список их "дружественных имен" ), после чего я хотел бы автоматически узнать номер COM-порта выбранного устройства.
Как я могу сделать это в С#? (оценивается решение, не зависящее от установленного пакета bluetooth).
Спасибо заранее.
Ответы
Ответ 1
См. мой ответ на Widcomm bluetooth: как открыть виртуальный COM для моего понимания лицензии: использование двоичной версии является бесплатным для коммерческого использования. И также, что я поддерживаю библиотеку.
Итак, небольшое небольшое отступление. Я не большой поклонник виртуальных COM-портов. Мне кажется, гораздо проще использовать прямое соединение "сокетов", а не пытаться настроить COM-порт и попытаться найти, какое имя оно было создано (см. Ниже!), А затем открыть SerialPort, чтобы использовать его, а затем, если соединение потеряно, никто не знает и просто пытается повторить попытку... С библиотекой гораздо проще просто создать и использовать это прямое соединение Bluetooth!
Однако вам может понадобиться решение вашей текущей задачи на данный момент.:-) Итак, используйте WMI, чтобы найти текущие COM-порты на месте и посмотреть, есть ли они для вашего устройства. Например, в PowerShell:
C:\> Get-WmiObject -query "select DeviceID,PNPDeviceID from Win32_SerialPort"
...
...
DeviceID : COM66
PNPDeviceID : BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}\7&1D80ECD3&0&00803A686519_C00000003
В этой большой длинной строке вы видите адрес целевого устройства: 00803A686519. Можно использовать WMI из .NET, выполнить этот запрос, отфильтровать те, что есть с "BTHENUM", а затем проанализировать адрес.
Если вам нужно создать новый виртуальный COM-порт Bluetooth, используйте API 32feet.NET BluetoothDeviceInfo.SetServiceState(BluetoothService.SerialPort). См. Раздел "Последовательные порты Bluetooth" в Руководстве пользователя, например. в http://www.alanjmcf.me.uk/comms/bluetooth/32feet.NET%20--%20User%20Guide.html и документация класса в релизе.
К сожалению, собственный API Win32, который мы вызываем, не указывает, какое имя COM-порта он создал!:-( Поэтому запустите запрос WMI до и после вызова, чтобы узнать, какое новое имя появилось (или используйте System.IO.Ports.SerialPort.GetPortNames как его более простой).
Это все зависит от стека Microsoft Bluetooth. Я не исследовал, как ведут себя другие стеки в этом отношении. После короткой проверки последовательные порты Widcomm отображаются в SerialPort.GetPortNames, но не в запросе WMI...
Ответ 2
Во-первых, создайте Searcher объекта управления для поиска в базе данных WMI:
ManagementObjectSearcher serialSearcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_SerialPort");
Далее, используйте LINQ, чтобы получить все последовательные порты в запросе:
var query = from ManagementObject s in serialSearcher.Get()
select new { Name = s["Name"], DeviceID = s["DeviceID"], PNPDeviceID = s["PNPDeviceID"] }; // DeviceID -- > PNPDeviceID
Теперь вы можете распечатать все COM-порты, их дружественные имена, и вы можете даже фильтровать через свой PNPDeviceID, чтобы найти адрес устройства Bluetooth. Вот пример:
foreach (var port in query)
{
Console.WriteLine("{0} - {1}", port.DeviceID, port.Name);
var pnpDeviceId = port.PNPDeviceID.ToString();
if(pnpDeviceId.Contains("BTHENUM"))
{
var bluetoothDeviceAddress = pnpDeviceId.Split('&')[4].Split('_')[0];
if (bluetoothDeviceAddress.Length == 12 && bluetoothDeviceAddress != "000000000000")
{
Console.WriteLine(" - Address: {0}", bluetoothDeviceAddress);
}
}
}
Ответ 3
Возможно, это не то, что вы ищете, и, возможно, вы уже нашли свой ответ...
Я только что нашел вопрос не так, как ваш, но работал у меня. С помощью этого вы можете узнать, какой из ваших COM-портов находится на устройстве Bluetooth:
fooobar.com/questions/424102/...
Я надеюсь, что это поможет. Если вы узнаете, как сделать то, что вы хотели, сообщите мне. Спасибо.
Ответ 4
Мне удалось получить имя Bluetooth и COM-порт, вставив раздел реестра
Псевдокод для получения информации о bluetooth приведен ниже:
- перечислить весь COM-порт, доступный в PNP
- получить класс deviceGuid
- найдите адрес Bluetooth из классаGuid
- Когда адрес Bluetooth известен, имя Bluetooth можно получить из этого реестра
SYSTEM\CurrentControlSet\Services\BTHPORT\Parameters\Devices
Ниже приведен код, просто вызовите GetBluetoothPort(), он вернет список устройств bluetooth, и вы можете подключить их, передав номер COM-порта классу SerialPort
public static string[] GetBluetoothPort()
{
Regex regexPortName = new Regex(@"(COM\d+)");
List<string> portList = new List<string>();
ManagementObjectSearcher searchSerial = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity");
foreach (ManagementObject obj in searchSerial.Get()) {
string name = obj["Name"] as string;
string classGuid = obj["ClassGuid"] as string;
string deviceID = obj["DeviceID"] as string;
if (classGuid != null && deviceID != null) {
if (String.Equals(classGuid, "{4d36e978-e325-11ce-bfc1-08002be10318}", StringComparison.InvariantCulture)) {
string[] tokens = deviceID.Split('&');
if (tokens.Length >= 4) {
string[] addressToken = tokens[4].Split('_');
string bluetoothAddress = addressToken[0];
Match m = regexPortName.Match(name);
string comPortNumber = "";
if (m.Success) {
comPortNumber = m.Groups[1].ToString();
}
if (Convert.ToUInt64(bluetoothAddress, 16) > 0) {
string bluetoothName = GetBluetoothRegistryName(bluetoothAddress);
portList.Add(String.Format("{0} {1} ({2})", bluetoothName, bluetoothAddress, comPortNumber));
}
}
}
}
}
return portList.ToArray();
}
private static string GetBluetoothRegistryName(string address)
{
string deviceName = "";
string registryPath = @"SYSTEM\CurrentControlSet\Services\BTHPORT\Parameters\Devices";
string devicePath = String.Format(@"{0}\{1}", registryPath, address);
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(devicePath)) {
if (key != null) {
Object o = key.GetValue("Name");
byte[] raw = o as byte[];
if (raw != null) {
deviceName = Encoding.ASCII.GetString(raw);
}
}
}
return deviceName;
}
Ответ 5
Итак, чтобы получить информацию о удаленном устройстве, включая его имя, используя 32feet.NET:
BluetoothAddress addr = ... ...
BluetoothDeviceInfo info = new BluetoothDeviceInfo(addr);
string name = info.DeviceName;
Если вы не используете библиотеку, вам придется P/Invoke Win32 BluetoothGetDeviceInfo.
Ответ 6
private static string FindSerialPortForRFIDReaderCore()
{
string serialPort = "";
List<string> ports = new List<string>();
System.Management.ManagementObjectSearcher Searcher = new System.Management.ManagementObjectSearcher("Select * from WIN32_SerialPort");
foreach (System.Management.ManagementObject Port in Searcher.Get())
{
if (Port["PNPDeviceID"].ToString().ToUpper().Contains("MacAddress"))
ports.Add(Port["DeviceID"].ToString());
}
if (ports.Count > 1) // There are more than one Serial Ports created for the bluetooth device.
serialPort = ports.OrderByDescending(p => p).FirstOrDefault();
else if(ports.Count == 1)
serialPort = ports[0];
return serialPort;
}