8

I want to create a console alternative to the 'Bluetooth and Other devices' dialog that is built into Windows for controlling Bluetooth devices. Using Windows.Devices.Enumeration API, I can pair and unpair devices. However, Bluetooth audio devices also have a connection feature (see the screenshot below). I would like my application to replicate what happens when I press the Connect button in this UI dialog. enter image description here

Update

Currently, there is no API that could be used to solve my problem. There is a very good discussion on Github about this topic that contains descriptions of available solutions and explains why they don't work.

PolarBear
  • 1,117
  • 15
  • 24
  • 1
    Unfortunately there is no public API to do exactly the same thing. However it can be simulated by using BluetoothSetServiceState() function. – Mike Petrichenko Jun 21 '20 at 18:07
  • @MikePetrichenko, thank you for your reply. Do you know if there is an analog of `BluetoothSetServiceState()` function for UWP apps? Maybe `Windows.Devices.Enumeration` namespace have something similar? – PolarBear Jan 17 '22 at 07:00
  • 1
    I do no think there is any analog. – Mike Petrichenko Jan 17 '22 at 07:14

1 Answers1

6

So far, I have found a workaround that allows Windows to connect to Bluetooth audio devices. It is based on an answer from Bernard Moeskops. However, to make it work, the following needs to be taken into account:

  • Bluetooth audio devices can be registered as multiple PnP devices, and you need to toggle each one.
  • It seems that waiting for 10 seconds between enabling and disabling is not necessary.
  • "Disable-PnpDevice" and "Enable-PnpDevice" commands require admin rights.

I have created a PowerShell script that worked for me (you need to change the $headphonesName variable to the name of your audio device):

# "Disable-PnpDevice" and "Enable-PnpDevice" commands require admin rights
#Requires -RunAsAdministrator

# Substitute it with the name of your audio device.
# The audio device you are trying to connect to should be paired.
$headphonesName = "WH-1000XM3"

$bluetoothDevices = Get-PnpDevice -class Bluetooth

# My headphones are recognized as 3 devices:
# * WH-1000XM3
# * WH-1000XM3 Avrcp Transport
# * WH-1000XM3 Avrcp Transport
# It is not enough to toggle only 1 of them. We need to toggle all of them.
$headphonePnpDevices = $bluetoothDevices | Where-Object { $_.Name.StartsWith("$headphonesName") }

if(!$headphonePnpDevices) {
    Write-Host "Coudn't find any devices related to the '$headphonesName'"
    Write-Host "Whole list of available devices is:"
    $bluetoothDevices
    return
}

Write-Host "The following PnP devices related to the '$headphonesName' headphones found:"
ForEach($d in $headphonePnpDevices) { $d }

Write-Host "`nDisable all these devices"
ForEach($d in $headphonePnpDevices) { Disable-PnpDevice -InstanceId $d.InstanceId -Confirm:$false }

Write-Host "Enable all these devices"
ForEach($d in $headphonePnpDevices) { Enable-PnpDevice -InstanceId $d.InstanceId -Confirm:$false }

Write-Host "The headphones should be connected now."

# After toggling, Windows "Bluetooth devices" dialog shows the state of the headphones as "Connected" but not as "Connected voice, music"
# However, after some time (around 5 seconds), the state changes to "Connected voice, music".
Write-Host "It may take around 10 seconds until the Windows starts showing audio devices related to these headphones."
PolarBear
  • 1,117
  • 15
  • 24
  • Thanks, this solution works for my B&W PX7 headset as well, with this one-line change: `$headphonesName = "PX7 Bowers & Wilkins"` I don't suppose you know how to define and consume the headset name as a command-line argument to the script? My Powershell skills are... um... lacking, or I would update the answer to make it more generic... – Stabledog May 11 '22 at 16:56
  • Added to [github](https://github.com/Stabledog/windows-bluetooth-hack) – Stabledog May 11 '22 at 18:45