Windows平台蓝牙串口:如何通过.NET编程获取连接状态
获取蓝牙串口设备(ESP32)连接状态的.NET实现方案
方法1:通过WMI查询设备状态
WMI可以直接读取Windows系统的设备信息,无需打开COM端口。需要引用System.Management命名空间,通过设备名称或硬件ID筛选目标设备,再判断其运行状态。
using System.Management; public static bool IsEsp32BluetoothConnected(string targetDeviceName) { // 构造查询语句,匹配蓝牙串口设备与目标名称 var query = new ObjectQuery( $"SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%Bluetooth%Serial%' AND Name LIKE '%{targetDeviceName}%'" ); using var searcher = new ManagementObjectSearcher(query); foreach (var device in searcher.Get()) { // Status为"OK"表示设备正常连接运行 var deviceStatus = device["Status"]?.ToString(); if (deviceStatus == "OK") { return true; } } return false; }
提示:如果需要更精准匹配,可以替换查询条件为设备的硬件ID(例如
HardwareID LIKE '%ESP32对应的VID/PID%'),避免名称重复导致误判。
方法2:调用Windows原生蓝牙API(P/Invoke)
通过P/Invoke调用Windows蓝牙底层函数,直接获取设备的连接状态标志,适合需要底层控制的场景。
using System; using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct BLUETOOTH_DEVICE_INFO { public int dwSize; public ulong Address; public uint ulClassofDevice; public bool fConnected; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 248)] public string szName; // 其他字段按需定义,此处保留核心字段 } [DllImport("bthprops.cpl", SetLastError = true, CharSet = CharSet.Unicode)] private static extern bool BluetoothGetDeviceInfo(IntPtr hRadio, ref BLUETOOTH_DEVICE_INFO pbtdi); [DllImport("bthprops.cpl", SetLastError = true)] private static extern IntPtr BluetoothFindFirstDevice(ref BLUETOOTH_DEVICE_INFO pbtdi, IntPtr hFind); [DllImport("bthprops.cpl", SetLastError = true)] private static extern bool BluetoothFindNextDevice(IntPtr hFind, ref BLUETOOTH_DEVICE_INFO pbtdi); public static bool CheckEsp32Connection(string deviceName) { var deviceInfo = new BLUETOOTH_DEVICE_INFO(); deviceInfo.dwSize = Marshal.SizeOf(typeof(BLUETOOTH_DEVICE_INFO)); var hFind = BluetoothFindFirstDevice(ref deviceInfo, IntPtr.Zero); if (hFind == IntPtr.Zero) return false; try { do { if (deviceInfo.szName.Contains(deviceName) && deviceInfo.fConnected) { return true; } } while (BluetoothFindNextDevice(hFind, ref deviceInfo)); } finally { // 释放查找句柄(需补充对应的DllImport函数) // BluetoothFindDeviceClose(hFind); } return false; }
注意:需要补充
BluetoothFindDeviceClose的P/Invoke定义以避免资源泄漏,完整实现可参考Windows蓝牙API文档。
方法3:使用UWP蓝牙API(.NET Core/.NET 5+)
对于现代.NET应用,可直接调用Windows.Devices.Bluetooth的UWP API,异步获取设备连接状态,无需复杂的底层调用。
using Windows.Devices.Bluetooth; using Windows.Devices.Enumeration; public static async Task<bool> GetEsp32ConnectionStatusAsync(string targetDeviceName) { // 获取所有蓝牙设备 var deviceSelector = BluetoothDevice.GetDeviceSelector(); var devices = await DeviceInformation.FindAllAsync(deviceSelector); foreach (var devInfo in devices) { if (devInfo.Name.Contains(targetDeviceName)) { var bluetoothDevice = await BluetoothDevice.FromIdAsync(devInfo.Id); return bluetoothDevice?.ConnectionStatus == BluetoothConnectionStatus.Connected; } } return false; }
提示:桌面应用中使用该API需要添加
Microsoft.Windows.SDK.ContractsNuGet包,并确保应用具备蓝牙访问权限。
关键注意事项
- 所有方案均无需打开COM端口,直接读取系统维护的设备状态。
- 优先使用设备硬件ID而非名称进行匹配,避免同名设备干扰。
- WMI方案兼容性最好,但查询效率略低;UWP API方案代码最简洁,适合现代.NET项目;原生API方案最灵活,适合复杂场景。
内容的提问来源于stack exchange,提问作者peregrinus
相关产品推荐
相关产品推荐

