通过c#中的设备名称获取蓝牙设备的COM端口

时间:2015-04-15 20:52:14

标签: c# bluetooth serial-port

我在C#中编写了一些代码来获取COM端口,其中映射了具有特定名称的蓝牙设备。我尝试了几种与here列出的解决方案类似的解决方案,但是没有一个解决方案我可以访问蓝牙设置窗口中的名称,如下图所示:

picture

如果它在该窗口上,我确定有办法找到它。有什么帮助吗?

非常感谢

3 个答案:

答案 0 :(得分:1)

尝试以下代码段。我用它在我每天使用的应用程序中按名称查找串行设备。

    public static bool DoesSerialDeviceExist(string name)
    {
        using (var search = new ManagementObjectSearcher
            ("SELECT * FROM WIN32_SerialPort"))
        {
            string[] portnames = SerialPort.GetPortNames();
            var ports = search.Get().Cast<ManagementBaseObject>().ToList();

            var tList = (from n in portnames
                         join p in ports on n equals p["DeviceID"].ToString()
                         select n + " - " + p["Caption"]).ToList();

            string serial = tList.FirstOrDefault(o => o.Contains(name));

            bool isAvailable = false;
            if (serial != null)
            {
                isAvailable = true;
            }

            return isAvailable;
        }
    }

答案 1 :(得分:1)

    private void FillInComportComboBox()
    {
        Hashtable PortNames = new Hashtable();
        string[] ports = System.IO.Ports.SerialPort.GetPortNames();

        //string st = ComPortList.Text;

        ComPortList.Items.Clear();

        if (ports.Length == 0)
        {
            ComPortList.Items.Add("ERROR: No COM ports exist");
        }
        else
        {
            PortNames = BuildPortNameHash(ports);
            //foreach (string s in ports)
            foreach(String s in PortNames.Keys)
            {
                //ComPortList.Items.Add(s + ":  " + (string)PortNames[s]);
                ComPortList.Items.Add(PortNames[s] + ": " + s);
            }
        }
    }




    // Begins recursive registry enumeration
    // <param name="oPortsToMap">array of port names (i.e. COM1, COM2, etc)</param>
    // <returns>a hashtable mapping Friendly names to non-friendly port values</returns>
    Hashtable BuildPortNameHash(string[] oPortsToMap)
    {
        Hashtable oReturnTable = new Hashtable();
        MineRegistryForPortName("SYSTEM\\CurrentControlSet\\Enum", oReturnTable, oPortsToMap);
        return oReturnTable;
    }
    // Recursively enumerates registry subkeys starting with strStartKey looking for 
    // "Device Parameters" subkey. If key is present, friendly port name is extracted.
    // <param name="strStartKey">the start key from which to begin the enumeration</param>
    // <param name="oTargetMap">hashtable that will get populated with 
    // friendly-to-nonfriendly port names</param>
    // <param name="oPortNamesToMatch">array of port names (i.e. COM1, COM2, etc)</param>
    void MineRegistryForPortName(string strStartKey, Hashtable oTargetMap, string[] oPortNamesToMatch)
    {
        if (oTargetMap.Count >= oPortNamesToMatch.Length)
            return;
        RegistryKey oCurrentKey = Registry.LocalMachine;

        try
        {
            oCurrentKey = oCurrentKey.OpenSubKey(strStartKey);

            string[] oSubKeyNames = oCurrentKey.GetSubKeyNames();
            if (((IList<string>)oSubKeyNames).Contains("Device Parameters") && strStartKey != "SYSTEM\\CurrentControlSet\\Enum")
            {
                object oPortNameValue = Registry.GetValue("HKEY_LOCAL_MACHINE\\" + strStartKey + "\\Device Parameters", "PortName", null);

                if (oPortNameValue == null || ((IList<string>)oPortNamesToMatch).Contains(oPortNameValue.ToString()) == false)
                    return;
                object oFriendlyName = Registry.GetValue("HKEY_LOCAL_MACHINE\\" + strStartKey, "FriendlyName", null);

                string strFriendlyName = "N/A";

                if (oFriendlyName != null)
                    strFriendlyName = oFriendlyName.ToString();
                if (strFriendlyName.Contains(oPortNameValue.ToString()) == false)
                    strFriendlyName = string.Format("{0} ({1})", strFriendlyName, oPortNameValue);
                oTargetMap[strFriendlyName] = oPortNameValue;
                //oTargetMap[oPortNameValue] = strFriendlyName;
            }
            else
            {
                foreach (string strSubKey in oSubKeyNames)
                    MineRegistryForPortName(strStartKey + "\\" + strSubKey, oTargetMap, oPortNamesToMatch);
            }
        }
        catch
        {

        }
    }

答案 2 :(得分:-1)

寻找解决方案后, 这是我发现的(我正在将其用于我的项目)

Main()
{

    AvailablePorts ports = new AvailablePorts();
    ports.GetBluetoothCOMPort();
    System.Collections.ObjectModel.ObservableCollection<COMPort> obs = ports.COMPorts;

}

现在,创建一个新类并添加这些引用

using System;
using System.Collections.Generic;
using System.Management;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Globalization;
using System.Collections.ObjectModel;
using System.Windows;
using System.Management.Automation;


public class AvailablePorts
{
    private ObservableCollection<COMPort> comPorts = new ObservableCollection<COMPort>();
    public ObservableCollection<COMPort> COMPorts
    {
        get => comPorts;
        set
        {
            comPorts = value;
        }
    }

    private string ExtractBluetoothDevice(string pnpDeviceID)
    {
        int startPos = pnpDeviceID.LastIndexOf('_') + 1;
        return pnpDeviceID.Substring(startPos);
    }

    private string ExtractDevice(string pnpDeviceID)
    {
        int startPos = pnpDeviceID.LastIndexOf('&') + 1;
        int length = pnpDeviceID.LastIndexOf('_') - startPos;
        return pnpDeviceID.Substring(startPos, length);
    }

    private string ExtractCOMPortFromName(string name)
    {
        int openBracket = name.IndexOf('(');
        int closeBracket = name.IndexOf(')');
        return name.Substring(openBracket + 1, closeBracket - openBracket - 1);
    }

    private string ExtractHardwareID(string fullHardwareID)
    {
        int length = fullHardwareID.LastIndexOf('_');
        return fullHardwareID.Substring(0, length);
    }

    private bool TryFindPair(string pairsName, string hardwareID, List<ManagementObject> bluetoothCOMPorts, out COMPort comPort)
    {
        foreach (ManagementObject bluetoothCOMPort in bluetoothCOMPorts)
        {
            string itemHardwareID = ((string[])bluetoothCOMPort["HardwareID"])[0];
            if (hardwareID != itemHardwareID && ExtractHardwareID(hardwareID) == ExtractHardwareID(itemHardwareID))
            {
                comPort = new COMPort(ExtractCOMPortFromName(bluetoothCOMPort["Name"].ToString()), Direction.INCOMING, pairsName);
                return true;
            }
        }
        comPort = null;
        return false;
    }

    private string GetDataBusName(string pnpDeviceID)
    {
        using (PowerShell PowerShellInstance = PowerShell.Create())
        {
            PowerShellInstance.AddScript($@"Get-PnpDeviceProperty -InstanceId '{pnpDeviceID}' -KeyName 'DEVPKEY_Device_BusReportedDeviceDesc' | select-object Data");

            Collection<PSObject> PSOutput = PowerShellInstance.Invoke();

            foreach (PSObject outputItem in PSOutput)
            {
                if (outputItem != null)
                {
                    Console.WriteLine(outputItem.BaseObject.GetType().FullName);
                    foreach (var p in outputItem.Properties)
                    {
                        if (p.Name == "Data")
                        {
                            return p.Value?.ToString();
                        }
                    }
                }
            }
        }
        return string.Empty;
    }


    public void GetBluetoothCOMPort()
    {
        COMPorts.Clear();


        ManagementObjectCollection results = new ManagementObjectSearcher(
            @"SELECT PNPClass, PNPDeviceID, Name, HardwareID FROM Win32_PnPEntity WHERE (Name LIKE '%COM%' AND PNPDeviceID LIKE '%BTHENUM%' AND PNPClass = 'Ports') OR (PNPClass = 'Bluetooth' AND PNPDeviceID LIKE '%BTHENUM\\DEV%')").Get();

        List<ManagementObject> bluetoothCOMPorts = new List<ManagementObject>();
        List<ManagementObject> bluetoothDevices = new List<ManagementObject>();

        foreach (ManagementObject queryObj in results)
        {
            if (queryObj["PNPClass"].ToString() == "Bluetooth")
            {
                bluetoothDevices.Add(queryObj);
            }
            else if (queryObj["PNPClass"].ToString() == "Ports")
            {
                bluetoothCOMPorts.Add(queryObj);
            }
        }

        foreach (ManagementObject bluetoothDevice in bluetoothDevices)
        {
            foreach (ManagementObject bluetoothCOMPort in bluetoothCOMPorts)
            {
                string comPortPNPDeviceID = bluetoothCOMPort["PNPDeviceID"].ToString();
                if (ExtractBluetoothDevice(bluetoothDevice["PNPDeviceID"].ToString()) == ExtractDevice(comPortPNPDeviceID))
                {
                    COMPort outgoingPort = new COMPort(ExtractCOMPortFromName(bluetoothCOMPort["Name"].ToString()), Direction.OUTGOING, $"{bluetoothDevice["Name"].ToString()} \'{GetDataBusName(comPortPNPDeviceID)}\'");

                    Application.Current.Dispatcher.Invoke(() => {
                        COMPorts.Add(outgoingPort);
                    });

                    if (TryFindPair(bluetoothDevice["Name"].ToString(), ((string[])bluetoothCOMPort["HardwareID"])[0], bluetoothCOMPorts, out COMPort incomingPort))
                    {
                        Application.Current.Dispatcher.Invoke(() => {
                            COMPorts.Add(incomingPort);
                        });
                    }
                }
            }
        }
    }
}



public class COMPort : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private string comPortPort;
    public string SerialPort
    {
        get => comPortPort;
        set
        {
            comPortPort = value;
            RaisePropertyChanged();
        }
    }

    private Direction comPortDirection;
    public Direction Direction
    {
        get => comPortDirection;
        set
        {
            comPortDirection = value;
            RaisePropertyChanged();
        }
    }

    private string comPortName;
    public string Name
    {
        get => comPortName;
        set
        {
            comPortName = value;
            RaisePropertyChanged();
        }
    }

    public COMPort(string comPortPort, Direction comPortDirection, string comPortName)
    {
        SerialPort = comPortPort;
        Direction = comPortDirection;
        Name = comPortName;
    }
}


public class DirectionConverter 
{
    private const string UNDEFINED_DIRECTION = "UNDEFINED";
    private const string INCOMING_DIRECTION = "Incoming";
    private const string OUTGOING_DIRECTION = "Outgoing";

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        switch ((Direction)value)
        {
            case Direction.UNDEFINED:
                return UNDEFINED_DIRECTION;
            case Direction.INCOMING:
                return INCOMING_DIRECTION;
            case Direction.OUTGOING:
                return OUTGOING_DIRECTION;
        }

        return string.Empty;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

public enum Direction
{
    UNDEFINED,
    INCOMING,
    OUTGOING
}

发现于: https://social.msdn.microsoft.com/Forums/Azure/en-US/b9d0adc3-b489-4245-91b9-6016a89302b9/get-bluetooth-com-ports?forum=csharpgeneral