如何在 Windows 上连接蓝牙设备?

Posted

技术标签:

【中文标题】如何在 Windows 上连接蓝牙设备?【英文标题】:How to connect to bluetooth device on Windows? 【发布时间】:2021-10-03 14:24:20 【问题描述】:

我希望允许用户直接从应用程序连接到配对的音频设备,而不是手动导航到蓝牙设置。

我正在使用 WinRT API 成功列出所有蓝牙设备:

var result = await DeviceInformation.FindAllAsync(BluetoothDevice.GetDeviceSelector());
// allow user to select a device
DeviceInfo d = await SelectDevice(result);
BluetoothDevice bluetoothDevice = await BluetoothDevice.FromIdAsync(d.Id);

由于 WinRT-Apis 不公开任何“连接”接口(请记住,我想连接设备,因为 Windows 自己不会与它通信),我正在探索使用 P/Invoke,所以我使用以下阅读this answer on superuser.com,建议使用BluetoothSetServiceState


// Definitions
private const string bluetoothDll = "bthprops.cpl";

[DllImport(bluetoothDll, ExactSpelling = true, SetLastError = true)]
private static extern uint BluetoothSetServiceState(IntPtr hRadio, ref BLUETOOTH_DEVICE_INFO pbtdi, ref Guid pGuidService, uint dwServiceFlags);

[DllImport(bluetoothDll, SetLastError = true)]
private static extern IntPtr BluetoothFindFirstRadio(ref Bluetooth_Find_Radio_Params pbtfrp, out IntPtr phRadio);

[DllImport(bluetoothDll, SetLastError = true)]
private static extern bool BluetoothFindRadioClose(IntPtr findHandle);

[DllImport(bluetoothDll, SetLastError = true)]
private static extern uint BluetoothGetDeviceInfo(IntPtr hRadio, ref BLUETOOTH_DEVICE_INFO pbtdi);

private const uint BLUETOOTH_SERVICE_DISABLE = 0;
private const uint BLUETOOTH_SERVICE_ENABLE = 0x00000001;

// Code (using the bluetoothDevice obtained from the WinRT Api)
using(var pointer = GetRadioPointer())

    BLUETOOTH_DEVICE_INFO deviceInfo = new BLUETOOTH_DEVICE_INFO
    
        Address = bluetoothDevice.BluetoothAddress,
        dwSize = (uint)Marshal.SizeOf<BLUETOOTH_DEVICE_INFO>()
    ;

    uint result = BluetoothGetDeviceInfo(pointer.Handle, ref deviceInfo);

    Guid serviceRef = InTheHand.Net.Bluetooth.BluetoothService.Handsfree;
    result = BluetoothSetServiceState(pointer.Handle, ref deviceInfo, ref serviceRef, 1);


// I get the radio like this:

private RadioHandle GetRadioPointer()

    Bluetooth_Find_Radio_Params pbtfrp = new Bluetooth_Find_Radio_Params();
    pbtfrp.Initialize();

    IntPtr findHandle = IntPtr.Zero;
    try
    
        findHandle = BluetoothFindFirstRadio(ref pbtfrp, out IntPtr phRadio);
        return new RadioHandle(phRadio);
    
    finally
    
        if (findHandle != IntPtr.Zero)
        
            BluetoothFindRadioClose(findHandle);
        
    

但是,我无法让它工作。 BluetoothSetServiceState 总是返回 87,也就是 ERROR_INVALID_PARAMETER 并且没有任何反应。关于如何解决这个问题的任何想法?使用超级用户帖子中引用的命令行工具,它可以工作...

感谢您的帮助。

【问题讨论】:

【参考方案1】:

为什么你会期望以下行会起作用:

private const string bluetoothDll = "bthprops.cpl";

当MSDN's page 声明:

DLL: Bthprops.dll

?

【讨论】:

嗯,这很奇怪,但就是这样:***.com/questions/19436462/…【参考方案2】:

我自己偶然发现了它,现在它可以工作了。根据服务是否已经处于状态(即使设备已断开连接),您需要先将其关闭。因此,将其关闭并重新打开即可:

BluetoothSetServiceState(pointer.Handle, ref deviceInfo, ref serviceRef, 0);
BluetoothSetServiceState(pointer.Handle, ref deviceInfo, ref serviceRef, 1);

事实证明,如果您枚举服务,将所有设备关闭并重新打开,您就可以连接设备。通过全部关闭断开连接。当最后一个关闭时,Windows 会断开设备连接。

【讨论】:

以上是关于如何在 Windows 上连接蓝牙设备?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows 10 上控制蓝牙 LE 连接?

在 Windows 10 上获取已连接的蓝牙设备列表

如何连接蓝牙低功耗设备

蓝牙LE设备在Windows 10 v1709中停止连接

蓝牙无线键盘如何连接电脑?

mac电脑如何连接多个蓝牙设备