Skip to content

CarlosOnline/BluetoothDiscovery

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 

Repository files navigation

BluetoothDiscovery

Discover Bluetooth Devices from c# using registry

Fast & easy code to discover blue tooth devices & their COM Ports on Windows 7 & Windows 8.

Much faster than using the Powershell commands.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Win32;

namespace BlueToothDevices
{
    /// Using the class
    class Program
    {
        static void Main(string[] args)
        {
            Bluetooth.VerboseMode = args.Length > 0 && args[0] == "true";
            foreach (var device in Bluetooth.GetBluetoothDevices())
            {
                Console.WriteLine("{0}", device);
            }

            Bluetooth.VerboseMode = false;
            foreach (var port in Bluetooth.DeviceNames)
            {
                Console.WriteLine("Device: {0}", port);
            }
        }
    }
    
    /// The Bluetooth discovery code
    
    public class BluetoothDevice
    {
        public string Name { get; set; }
        public string Port { get; set; }
        public string DeviceId { get; set; }

        public override string ToString()
        {
            return string.Format("{0} [ {1} ] {2}", Name, Port, DeviceId);
        }
    }

    public class Bluetooth
    {
        private const string NullDeviceId = "000000000000";
        private const string BluetoothRegKey = @"SYSTEM\CurrentControlSet\Enum\BTHENUM";
        private const string BluetoothRegKey7 = @"SYSTEM\CurrentControlSet\services\BTHPORT\Parameters\LocalServices";
        private readonly Dictionary<string, BluetoothDevice> _devices = new Dictionary<string, BluetoothDevice>();
        public BluetoothDevice[] Devices { get { return _devices.Values.ToArray(); } }

        public static bool VerboseMode { get; set; }
        private static void Verbose(string message, params object[] args)
        {
            if (VerboseMode)
                Console.WriteLine("{0}", string.Format(message, args));
        }

        public static List<string> DeviceNames
        {
            get
            {
                var devices = new List<string>();
                foreach (var device in GetBluetoothDevices())
                {
                    if (string.IsNullOrEmpty(device.Port))
                        continue;

                    devices.Add(string.Format("{0} {1}", device.Name, device.Port));
                }
                return devices;
            }
        }

        public static BluetoothDevice[] GetBluetoothDevices()
        {
            var bluetooth = new Bluetooth();
            bluetooth.GetDeviceNames();
            bluetooth.SetDevicePorts();
            return bluetooth.Devices;
        }

        private void GetDeviceNamesForWindows7()
        {
            using (var key = Registry.LocalMachine.OpenSubKey(BluetoothRegKey7, false))
            {
                if (key == null)
                {
                    Console.WriteLine("GetLocalServices: missing HKLM {0}", BluetoothRegKey7);
                    return;
                }

                foreach (var name in key.GetSubKeyNames())
                {
                    using (var k1 = OpenSubKey(key, name))
                    {
                        if (k1 == null)
                            continue;

                        foreach (var pnpName in k1.GetSubKeyNames())
                        {
                            using (var k2 = OpenSubKey(k1, pnpName))
                            {
                                if (k2 == null)
                                    continue;

                                var friendlyName = GetValue(k2, "ServiceName");
                                var deviceId = GetDeviceToken(GetValue(k2, "AssocBdAddr"));
                                if (string.IsNullOrEmpty(deviceId))
                                {
                                    Console.WriteLine("GetLocalServices: Missing required deviceId");
                                    continue;
                                }

                                var deviceInfo = new BluetoothDevice
                                {
                                    Name = friendlyName,
                                    DeviceId = deviceId,
                                };
                                Verbose("GetLocalServices: Add {0}", deviceInfo);
                                _devices.Add(deviceId, deviceInfo);
                            }
                        }
                    }
                }
            }
        }

        private void GetDeviceNames()
        {
            GetDeviceNamesForWindows7();
            GetDeviceNamesForWindows8();
        }

        private void GetDeviceNamesForWindows8()
        {
            using (var key = Registry.LocalMachine.OpenSubKey(BluetoothRegKey, false))
            {
                if (key == null)
                {
                    Console.WriteLine("GetDeviceNamesForWindows8: missing HKLM {0}", BluetoothRegKey);
                    return;
                }

                foreach (var name in key.GetSubKeyNames())
                {
                    using (var k1 = OpenSubKey(key, name))
                    {
                        if (k1 == null)
                            continue;

                        foreach (var pnpName in k1.GetSubKeyNames())
                        {
                            using (var pnpKey = OpenSubKey(k1, pnpName))
                            {
                                if (pnpKey == null)
                                    continue;

                                BluetoothDevice deviceInfo;
                                var deviceId = GetDeviceName2(pnpName);
                                if (string.IsNullOrEmpty(deviceId))
                                    continue;

                                var friendlyName = GetValue(pnpKey, "FriendlyName", pnpName);
                                if (!_devices.TryGetValue(deviceId, out deviceInfo))
                                {
                                    deviceInfo = new BluetoothDevice();
                                    _devices.Add(deviceId, deviceInfo);
                                }

                                if (string.IsNullOrEmpty(deviceInfo.Name))
                                    deviceInfo.Name = friendlyName;
                                deviceInfo.DeviceId = deviceId;
                                Verbose("GetDevicenamesForWindows8: Add {0}", deviceInfo);
                            }
                        }
                    }
                }
            }
        }

        private void SetDevicePorts()
        {
            using (var key = Registry.LocalMachine.OpenSubKey(BluetoothRegKey, false))
            {
                if (key == null)
                {
                    Console.WriteLine("SetDevicePorts: missing HKLM {0}", BluetoothRegKey);
                    return;
                }

                foreach (var name in key.GetSubKeyNames())
                {
                    using (var k1 = OpenSubKey(key, name))
                    {
                        if (k1 == null)
                            continue;

                        foreach (var pnpName in k1.GetSubKeyNames())
                        {
                            using (var pnpKey = OpenSubKey(k1, pnpName))
                            {
                                if (pnpKey == null)
                                    continue;

                                BluetoothDevice deviceInfo;
                                var isLocalMfg = name.Contains("LOCALMFG");
                                if (!isLocalMfg)
                                    continue;

                                var deviceId = GetDeviceName(pnpName);
                                if (deviceId == NullDeviceId)
                                    continue;

                                if (string.IsNullOrEmpty(deviceId))
                                {
                                    Console.WriteLine("SetDevicePorts:Missing DeviceId for {0}\\{1}", name, pnpName);
                                    continue;
                                }

                                if (!_devices.TryGetValue(deviceId, out deviceInfo))
                                {
                                    Console.WriteLine("SetDevicePorts: Missing DeviceInfo for device: {0} {1}\\{2}", deviceId, name, pnpName);
                                    continue;
                                }

                                if (!string.IsNullOrEmpty(deviceInfo.Port))
                                    continue;

                                if (!pnpKey.GetSubKeyNames().Contains("Device Parameters"))
                                {
                                    Console.WriteLine("SetDevicePorts:Missing Device Parameters for {0}\\{1}", name, pnpName);
                                    continue;
                                }

                                var portName = GetPortName(pnpKey);
                                if (string.IsNullOrEmpty(portName))
                                {
                                    Console.WriteLine("SetDevicePorts: Missing PortName for {0}", pnpName);
                                    continue;
                                }
                                deviceInfo.Port = portName;
                            }
                        }
                    }
                }
            }
        }

        public static string GetDeviceGuid(string value)
        {
            Verbose("GetDeviceGuid: {0}", value);

            var idx = value.IndexOf("}");
            if (idx > 0)
            {
                var id = value.Substring(0, idx);
                if (id.Length == 39)
                {
                    Verbose("GetDeviceGuid: returns {0}", id);
                    return id;
                }
            }
            return null;
        }

        private static string GetDeviceName(string value)
        {
            //Verbose("GetDeviceName: {0}", value);

            var parts1 = value.Split('_');
            if (parts1.Length <= 1)
            {
                Console.WriteLine("GetDeviceName: name parse error on {0}", value);
                return "";
            }

            var parts2 = parts1[0].Split('&');
            if (parts2.Length == 0)
            {
                Console.WriteLine("GetDeviceName: name parse error on {0}", value);
                return "";
            }
            var id = parts2[parts2.Length - 1];

            Verbose("GetDeviceName: returns {0}", id);
            return id;
        }

        private static string GetDeviceName2(string value)
        {
            //Verbose("GetDevicename2: {0}", value);

            var parts = value.Split('_');
            if (parts.Length <= 1)
            {
                Console.WriteLine("GetDeviceName2: name parse error on {0}", value);
                return "";
            }
            var deviceId = parts[1];
            if (string.IsNullOrEmpty(deviceId))
            {
                Console.WriteLine("GetDeviceName2: parse error on {0}", value);
                return "";
            }
            Verbose("GetDeviceName2: returns {0}", deviceId);
            return deviceId;
        }

        private static string GetPortName(RegistryKey key)
        {
            using (var paramsKey = OpenSubKey(key, "Device Parameters"))
            {
                if (paramsKey == null || !paramsKey.GetValueNames().Contains("PortName"))
                    return null;

                var portName = (string)paramsKey.GetValue("PortName");
                Verbose("GetPortName: {0}", portName);
                return portName;
            }
        }

        /// <summary>
        /// "AssocBdAddr"=hex:8f,68,c1,6c,6e,64,00,00 to 646E6CC1688F
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetDeviceToken(string value)
        {
            if (string.IsNullOrEmpty(value))
                return null;

            var parts = value.ToUpper().Split('-');
            if (parts.Length < 6)
                return null;

            var result = string.Join("", parts.Take(6).Reverse());
            Verbose("GetDeviceToken: {0}", result);

            return result;
        }

        private static string GetValue(RegistryKey key, string name, string defaultValue = null)
        {
            if (!key.GetValueNames().Contains(name))
            {
                Console.WriteLine("Missing Value: {0}", name);
                return defaultValue;
            }
            var value = key.GetValue(name);
            var result = value as string;
            if (result != null)
            {
                Verbose("GetValue: {0} {1}", name, result);
                return result;
            }
            var bytes = value as byte[];
            if (bytes != null)
            {
                result = BitConverter.ToString(bytes);
                Verbose("GetValue: {0} {1}", name, result);
                return result;
            }

            return null;
        }

        private static RegistryKey OpenSubKey(RegistryKey key, string name)
        {
            if (key == null)
                return null;

            var parent = key.Name.Replace(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\", "");
            Verbose("OpenSubKey: {0}\\{1}", parent, name);

            var result = key.OpenSubKey(name, false);
            if (result == null)
                Console.WriteLine("OpenSubKey: {0}\\{1}", parent, name);
            return result;
        }

    }
}

About

Discover Bluetooth Devices from c# using registry

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages