如何通过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
相关产品推荐
相关产品推荐

