You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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, &notifyInfo->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(&notifyParams, &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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 11:36:03