I want to create a console alternative to the 'Bluetooth and Other devices' dialog 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.
Use BluetoothDevicePairing utility
This console utility allows one to connect and disconnect Bluetooth audio devices like headphones, headsets, microphones, etc.
It uses Windows Core Audio API and is based on the implementation from ToothTray utility by @Sean Yu.
Alternative
It is a workaround that allows Windows to connect to Bluetooth audio devices. 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."
$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... –
Morula https://github.com/m2jean/ToothTray/ is the correct way to connect and disconnect bluetooth audio device by program and I think Win10 Win11 also use this way. But this tool has a bug, can not work properly in Win11. Call IMMDeviceEnumerator::EnumAudioEndpoints, change parameter EDataFlow from eCaptuer to eAll, can fix the bug. And I also code in csharp, everything is ok.
© 2022 - 2024 — McMap. All rights reserved.
BluetoothSetServiceState()
function for UWP apps? MaybeWindows.Devices.Enumeration
namespace have something similar? – Evince