Windows 10 下实现与系统蓝牙添加界面一致的命令行蓝牙搜索方案咨询
Windows命令行持续蓝牙扫描实现方案
1. 核心实现依赖
你之前的方案仅调用了单次蓝牙枚举接口,默认只会返回少量已配对/本地缓存的设备,和系统添加设备页的扫描逻辑差异较大。要复现系统级扫描效果,直接调用BluetoothAPIs.dll导出的原生Win32蓝牙API即可,核心用到的接口如下:
BluetoothRegisterForDeviceNotifications:注册蓝牙设备状态变更通知,实现设备出现、消失、属性更新的实时回调BluetoothFindFirstDevice/BluetoothFindNextDevice:触发主动扫描,拉取最新的周边蓝牙设备列表BluetoothGetDeviceInfo:获取设备名称、MAC地址、信号强度、配对状态等详细属性BluetoothUnregisterDeviceNotification:程序退出前注销通知,释放资源
2. 完整可运行C++示例代码
编译依赖Windows 10及以上版本SDK,使用MSVC编译器即可直接编译运行,支持Ctrl-C终止扫描:
#include <windows.h> #include <bluetoothapis.h> #include <stdio.h> #pragma comment(lib, "Bthprops.lib") static BOOL g_isRunning = TRUE; static HANDLE g_notifyHandle = NULL; // Ctrl-C信号处理回调 BOOL WINAPI ConsoleCtrlHandler(DWORD ctrlType) { if (ctrlType == CTRL_C_EVENT) { g_isRunning = FALSE; if (g_notifyHandle != NULL) { BluetoothUnregisterDeviceNotification(g_notifyHandle); } printf("\n扫描已终止\n"); return TRUE; } return FALSE; } // 蓝牙设备状态变更回调 VOID CALLBACK BtDeviceNotifyCallback(PVOID param, PBLUETOOTH_DEVICE_NOTIFICATION notifyInfo) { BLUETOOTH_DEVICE_INFO devInfo = { sizeof(BLUETOOTH_DEVICE_INFO) }; CopyMemory(&devInfo.Address, ¬ifyInfo->DeviceInfo.Address, sizeof(BTH_ADDR)); if (BluetoothGetDeviceInfo(NULL, &devInfo) != ERROR_SUCCESS) return; BYTE* mac = devInfo.Address.rgBytes; if (notifyInfo->dwEventType == BTE_DEVICE_ARRIVAL) { wprintf(L"[+] 发现设备:名称=%s,MAC=%02X:%02X:%02X:%02X:%02X:%02X,RSSI=%d\n", devInfo.szName, mac[5], mac[4], mac[3], mac[2], mac[1], mac[0], devInfo.rssi); } else if (notifyInfo->dwEventType == BTE_DEVICE_REMOVAL) { wprintf(L"[-] 设备消失:名称=%s,MAC=%02X:%02X:%02X:%02X:%02X:%02X\n", devInfo.szName, mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]); } } int main() { // 注册控制台终止信号处理 SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE); // 注册蓝牙设备全局通知 BLUETOOTH_NOTIFICATION_PARAMS notifyParams = { sizeof(BLUETOOTH_NOTIFICATION_PARAMS) }; notifyParams.pfnCallback = BtDeviceNotifyCallback; notifyParams.fListenForAllDevices = TRUE; DWORD ret = BluetoothRegisterForDeviceNotifications(¬ifyParams, &g_notifyHandle); if (ret != ERROR_SUCCESS) { printf("蓝牙通知注册失败,错误码:%d,请确保蓝牙已开启\n", ret); return 1; } // 扫描参数配置:10秒单次扫描,返回所有类型设备 BLUETOOTH_DEVICE_SEARCH_PARAMS searchParams = { sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS) }; searchParams.fIssueInquiry = TRUE; searchParams.fReturnAuthenticated = TRUE; searchParams.fReturnRemembered = TRUE; searchParams.fReturnUnknown = TRUE; searchParams.fReturnConnected = TRUE; searchParams.cTimeoutMultiplier = 10; printf("蓝牙扫描已启动,按Ctrl-C终止\n"); // 循环触发扫描,保持持续发现状态 while (g_isRunning) { HBLUETOOTH_DEVICE_FIND hFind = BluetoothFindFirstDevice(&searchParams, NULL); if (hFind != NULL) BluetoothFindDeviceClose(hFind); Sleep(10000); } return 0; }
3. 注意事项
- 运行前需确保系统蓝牙处于开启状态,且程序已获得蓝牙权限
- 未配对设备的信号强度默认不会实时返回,可通过修改扫描参数开启主动探测获取RSSI值
- 该实现仅兼容Windows 10及以上版本系统,不支持Windows 7及更早版本
内容的提问来源于stack exchange,提问作者sdbbs
相关产品推荐
相关产品推荐

