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

如何通过Windows API实现Windows蓝牙的开启与关闭(C++开发问询)

两种实现C++控制蓝牙开关的方案

方案一:Radio Manager API(Windows 10 1709及以上推荐)

Windows 10 1709版本后提供了Windows.Devices.Radios命名空间的API,可直接操作蓝牙无线电状态,比SetupDi更简洁。

代码示例

#include <windows.h>
#include <winrt/Windows.Devices.Radios.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <iostream>

using namespace winrt;
using namespace Windows::Devices::Radios;
using namespace Windows::Foundation::Collections;

int main()
{
    // 初始化WinRT环境
    init_apartment();

    try
    {
        // 获取所有无线电设备
        IVectorView<Radio> radios = Radio::GetRadiosAsync().get();

        for (Radio const& radio : radios)
        {
            // 筛选蓝牙类型的无线电
            if (radio.Kind() == RadioKind::Bluetooth)
            {
                RadioState currentState = radio.State();
                RadioState targetState = (currentState == RadioState::On) ? RadioState::Off : RadioState::On;

                // 请求切换状态(需要管理员权限)
                RadioAccessStatus status = radio.SetStateAsync(targetState).get();

                if (status == RadioAccessStatus::Allowed)
                {
                    std::cout << "蓝牙已" << (targetState == RadioState::On ? "开启" : "关闭") << std::endl;
                }
                else
                {
                    std::cout << "切换失败,权限不足或设备不支持" << std::endl;
                }
                return 0;
            }
        }
        std::cout << "未找到蓝牙设备" << std::endl;
    }
    catch (hresult_error const& ex)
    {
        std::cout << "错误: " << ex.message().c_str() << std::endl;
    }

    return 0;
}

注意事项

  • 项目需配置支持WinRT(VS中:项目属性 -> C/C++ -> 常规 -> 将“Consume Windows Runtime Extension”设为Yes)
  • 必须以管理员权限运行程序,否则SetStateAsync会返回权限不足的错误

方案二:SetupDi API(兼容Windows 7及以上)

通过设备管理器API直接控制蓝牙设备的启用/禁用,兼容性更强,但代码相对繁琐。

代码示例

#include <windows.h>
#include <setupapi.h>
#include <initguid.h>
#include <devguid.h>
#include <iostream>

#pragma comment(lib, "setupapi.lib")

BOOL ToggleBluetoothDevice(BOOL bEnable)
{
    HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_BLUETOOTH, NULL, NULL, DIGCF_PRESENT);
    if (hDevInfo == INVALID_HANDLE_VALUE)
    {
        std::cout << "获取设备列表失败,错误码: " << GetLastError() << std::endl;
        return FALSE;
    }

    SP_DEVINFO_DATA devInfoData = { 0 };
    devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    // 遍历蓝牙设备
    for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &devInfoData); i++)
    {
        SP_PROPCHANGE_PARAMS propChangeParams = { 0 };
        propChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
        propChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
        propChangeParams.Scope = DICS_FLAG_GLOBAL;
        propChangeParams.StateChange = bEnable ? DICS_ENABLE : DICS_DISABLE;

        // 发送状态变更请求
        if (!SetupDiSetClassInstallParams(hDevInfo, &devInfoData, &propChangeParams.ClassInstallHeader, sizeof(propChangeParams)))
        {
            std::cout << "设置安装参数失败,错误码: " << GetLastError() << std::endl;
            SetupDiDestroyDeviceInfoList(hDevInfo);
            return FALSE;
        }

        if (SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &devInfoData))
        {
            std::cout << "蓝牙设备已" << (bEnable ? "启用" : "禁用") << std::endl;
            SetupDiDestroyDeviceInfoList(hDevInfo);
            return TRUE;
        }
        else
        {
            std::cout << "调用安装器失败,错误码: " << GetLastError() << std::endl;
        }
    }

    std::cout << "未找到可操作的蓝牙设备" << std::endl;
    SetupDiDestroyDeviceInfoList(hDevInfo);
    return FALSE;
}

int main()
{
    // 切换蓝牙状态:TRUE为启用,FALSE为禁用
    ToggleBluetoothDevice(TRUE);
    return 0;
}

注意事项

  • 同样需要管理员权限运行
  • 部分蓝牙设备可能有多个子设备(比如蓝牙适配器和蓝牙音频设备),可通过读取设备名称进一步筛选目标设备
  • 错误码可通过FormatMessage获取更详细的描述

内容的提问来源于stack exchange,提问作者Barnabás

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 05:43:10