Как я могу узнать номер COM-порта устройства Bluetooth в C #? - PullRequest
16 голосов
/ 18 января 2010

Моя компания разработала устройство, которое обменивается данными с ПК через Bluetooth с помощью виртуального COM-порта.

Теперь нам нужно, чтобы пользователь сначала связал устройство с ПК (ОС MS Windows), а затем вручную ввел номер его com-порта в наше приложение (держу пари, что 95% пользователей не получат такой запрос).

Поэтому я хотел бы, чтобы мое приложение предоставило пользователю список сопряженных устройств Bluetooth (список их «дружественных имен»), а после этого я бы хотел автоматически узнать номер COM-порта выбранного устройства.

Как я могу сделать это в C #? (приветствуется решение, не зависящее от установленного стека Bluetooth).

Заранее спасибо.

Ответы [ 6 ]

9 голосов
/ 19 января 2010

См. Мой ответ на 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-интерфейс BluetoothDeviceInfo.SetServiceState (BluetoothService.SerialPort) от 32feet.NET. См. Раздел «Последовательные порты Bluetooth» в Руководстве пользователя, например, в http://www.alanjmcf.me.uk/comms/bluetooth/32feet.NET%20--%20User%20Guide.html, и документации класса в выпуске.

К сожалению, родной Win32 API, который мы вызываем, не говорит, какое имя COM-порта он создал! :-( Так что запустите запрос WMI до и после вызова, чтобы увидеть, какое новое имя появилось (или используйте System.IO.Ports.SerialPort.GetPortNames как его более простое).

Это все относится к стеку Microsoft Bluetooth. Я не исследовал, как ведут себя другие стеки в этом отношении. После краткой проверки последовательные порты Widcomm появляются в SerialPort.GetPortNames, но не в запросе WMI ...

4 голосов
/ 05 мая 2015

Сначала создайте средство поиска объектов управления для поиска в базе данных 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);
        }
    }
}
2 голосов
/ 30 марта 2016

Мне удается получить имя Bluetooth и COM-порт, перебирая ключ реестра

Псевдокод для получения информации о Bluetooth приведен ниже:

  • перечисляет все COM-порты, доступные в PNP
  • получить устройство classGuid
  • поиск адреса bluetooth из класса гид
  • когда известен адрес 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;
}
1 голос
/ 04 апреля 2012

Возможно, это не то, что вы ищете, и, возможно, вы уже нашли свой ответ ...

Я только что нашел вопрос, не совсем похожий на ваш, но работал для меня. С помощью этого вы можете узнать, какой из ваших COM-портов от устройства Bluetooth StackOverflow - определите, является ли последовательный порт нормальным COM или SPP

Надеюсь, это поможет как-то. Если вы узнаете, как делать то, что вы хотели, пожалуйста, дайте мне знать. Спасибо.

0 голосов
/ 25 апреля 2017
    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;
    }
0 голосов
/ 22 января 2010

Итак, чтобы получить информацию об удаленном устройстве, включая его имя, с помощью 32feet.NET сделайте:

BluetoothAddress addr = ... ...
BluetoothDeviceInfo info = new BluetoothDeviceInfo(addr);
string name = info.DeviceName;

Если библиотека не используется, вам придется P / Invoke Win32 BluetoothGetDeviceInfo.

...