Connect to bluetooth headset via shortcut Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
hotkeyuser1234
Posts: 92
Joined: 07 Mar 2020, 12:27

Connect to bluetooth headset via shortcut

Post by hotkeyuser1234 » 14 Nov 2020, 13:36

Dear community,

I found this code which is supposed to automatically open settings and connect with the device at the top of the list of prior devices:

Code: Select all

#SingleInstance,force
NumpadPgDn:: ;3 on Numpad
Run, bthprops.cpl
Sleep, 2000
Send, {tab}{tab}{enter}{tab}{enter}
Sleep, 200
Send,!{Tab}
return
However, I have keyboards and mice in my list of recent devices as well and thus just selecting the top device does not work, see here:
mouse-ahk.jpg
mouse-ahk.jpg (8.64 KiB) Viewed 8709 times
Is there the chance to edit the script so that it skips the first 4 devices in the peripherals section and take the first type of headphones? See here:
mouse-ahk.jpg
mouse-ahk.jpg (8.64 KiB) Viewed 8709 times
Thank you for your help!
Attachments
devices.jpg
devices.jpg (17.56 KiB) Viewed 8709 times

User avatar
mikeyww
Posts: 26588
Joined: 09 Sep 2014, 18:38

Re: Connect to bluetooth headset via shortcut

Post by mikeyww » 14 Nov 2020, 13:46

If it's the last entry, you could try adding {End} before one of the {Enter} listings. Give it a try. You might have to fiddle with it a bit. I think I would also add the following before the first Sleep.

Code: Select all

WinWaitActive, Devices and Printers,, 10
If ErrorLevel {
 MsgBox, 48, Error, The Bluetooth window was not found.
 Return
}
Below might be an alternative, but I have not tested it.

https://bluetoothinstaller.com/bluetooth-command-line-tools/

hotkeyuser1234
Posts: 92
Joined: 07 Mar 2020, 12:27

Re: Connect to bluetooth headset via shortcut

Post by hotkeyuser1234 » 15 Nov 2020, 04:10

Thanks, but unfortunately, I could not get it working this way as well. It keep showing "The Bluetooth window cannot be found", even after removing the text snippet from you (but while keeping {End}).

Do you have any other ideas how to achieve it?

User avatar
mikeyww
Posts: 26588
Joined: 09 Sep 2014, 18:38

Re: Connect to bluetooth headset via shortcut

Post by mikeyww » 15 Nov 2020, 07:38

OK, no luck there.

There is the command-line approach as cited. I usually do that for the sake of reliability, though it might take more work to set up. With your situation there, ImageSearch is also likely to work quite well because the headphone icon appears distinct. In advance, you would capture a small screenshot just of the headphones, and save it as an image file. When ready to connect, you would then search the screen (or preferably just that window) for that image, and then click on it.

Did you try the original script just to see if it interacts with your menu properly? If it does, then you should just be able to provide additional navigation keys to get you to the bottom of the menu. That was the idea with simply adding {End} at some point in the sequence.


User avatar
mikeyww
Posts: 26588
Joined: 09 Sep 2014, 18:38

Re: Connect to bluetooth headset via shortcut

Post by mikeyww » 15 Nov 2020, 10:52

Thank you, @malcev! That is probably a step better than the external command-line program.

hotkeyuser1234
Posts: 92
Joined: 07 Mar 2020, 12:27

Re: Connect to bluetooth headset via shortcut

Post by hotkeyuser1234 » 15 Nov 2020, 16:28

Thank you @malcev ! Are you more familiar with the API? If so, could you help me write some code that would allow to connect with the headphones?

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Connect to bluetooth headset via shortcut

Post by malcev » 15 Nov 2020, 16:46

No. I found it only today. :)

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Connect to bluetooth headset via shortcut

Post by malcev » 24 Nov 2020, 22:52

Found time to read about this api.
https://docs.microsoft.com/en-us/windows/win32/api/_bluetooth/
It does not really connects, but enable/disable bluetooth services for device - therefore connects/disconnects it.
The same api uses btcom I think.
Connection can be done like this

Code: Select all

deviceName := "jbl clip 3"

DllCall("LoadLibrary", "str", "Bthprops.cpl", "ptr")
toggle := toggleOn := 1
VarSetCapacity(BLUETOOTH_DEVICE_SEARCH_PARAMS, 24+A_PtrSize*2, 0)
NumPut(24+A_PtrSize*2, BLUETOOTH_DEVICE_SEARCH_PARAMS, 0, "uint")
NumPut(1, BLUETOOTH_DEVICE_SEARCH_PARAMS, 4, "uint")   ; fReturnAuthenticated
VarSetCapacity(BLUETOOTH_DEVICE_INFO, 560, 0)
NumPut(560, BLUETOOTH_DEVICE_INFO, 0, "uint")
loop
{
   If (A_Index = 1)
   {
      foundedDevice := DllCall("Bthprops.cpl\BluetoothFindFirstDevice", "ptr", &BLUETOOTH_DEVICE_SEARCH_PARAMS, "ptr", &BLUETOOTH_DEVICE_INFO, "ptr")
      if !foundedDevice
      {
         msgbox no bluetooth devices
         return
      }
   }
   else
   {
      if !DllCall("Bthprops.cpl\BluetoothFindNextDevice", "ptr", foundedDevice, "ptr", &BLUETOOTH_DEVICE_INFO)
      {
         msgbox no found
         break
      }
   }
   if (StrGet(&BLUETOOTH_DEVICE_INFO+64) = deviceName)
   {
      VarSetCapacity(Handsfree, 16)
      DllCall("ole32\CLSIDFromString", "wstr", "{0000111e-0000-1000-8000-00805f9b34fb}", "ptr", &Handsfree)   ; https://www.bluetooth.com/specifications/assigned-numbers/service-discovery/
      VarSetCapacity(AudioSink, 16)
      DllCall("ole32\CLSIDFromString", "wstr", "{0000110b-0000-1000-8000-00805f9b34fb}", "ptr", &AudioSink)
      loop
      {
         hr := DllCall("Bthprops.cpl\BluetoothSetServiceState", "ptr", 0, "ptr", &BLUETOOTH_DEVICE_INFO, "ptr", &Handsfree, "int", toggle)   ; voice
         if (hr = 0)
         {
            if (toggle = toggleOn)
               break
            toggle := !toggle
         }
         if (hr = 87)
            toggle := !toggle
      }
      loop
      {
         hr := DllCall("Bthprops.cpl\BluetoothSetServiceState", "ptr", 0, "ptr", &BLUETOOTH_DEVICE_INFO, "ptr", &AudioSink, "int", toggle)   ; music
         if (hr = 0)
         {
            if (toggle = toggleOn)
               break 2
            toggle := !toggle
         }
         if (hr = 87)
            toggle := !toggle
      }
   }
}
DllCall("Bthprops.cpl\BluetoothFindDeviceClose", "ptr", foundedDevice)
msgbox done
ExitApp
Also connection could be done using winsock bluetooth api.
https://docs.microsoft.com/en-us/windows/win32/bluetooth/bluetooth-programming-with-windows-sockets
Strange that connect method returns error with device address error, but really connects but We should send it in loop for about 10 seconds
Dont know why - complex api...

Code: Select all

deviceName := "jbl clip 3"

DllCall("LoadLibrary", "str", "ws2_32.dll", "ptr")
VarSetCapacity(WSADATA, 394 + (A_PtrSize - 2) + A_PtrSize, 0)
DllCall("ws2_32\WSAStartup", "ushort", 0x0202, "ptr", &WSADATA)
size := 1024
VarSetCapacity(WSAQUERYSETW, size, 0)
NumPut(size, WSAQUERYSETW, 0, "uint")
NumPut(NS_BTH := 16, WSAQUERYSETW, A_PtrSize*5, "uint")
DllCall("ws2_32\WSALookupServiceBeginW", "ptr", &WSAQUERYSETW, "uint", LUP_CONTAINERS := 0x0002, "ptr*", lphLookup)
loop
{
   if (DllCall("ws2_32\WSALookupServiceNextW", "ptr", lphLookup, "uint", 0x0002|0x0010|0x0100, "uint*", size, "ptr", &WSAQUERYSETW) = -1)   ; LUP_CONTAINERS|LUP_RETURN_NAME|LUP_RETURN_ADDR
   {
      error := DllCall("ws2_32\WSAGetLastError")
      if (error = 10110)   ; WSA_E_NO_MORE https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2
         msgbox device not found
      else
         msgbox % error
      exitapp
   }
   if (strget(numget(WSAQUERYSETW, A_PtrSize)) = deviceName)
   {
      socket := DllCall("ws2_32\socket", "int", AF_BTH := 32, "int", SOCK_STREAM := 1, "int", BTHPROTO_RFCOMM := 3)
      VarSetCapacity(SOCKADDR_BTH, 36, 0)
      NumPut(AF_BTH := 32, SOCKADDR_BTH, 0, "ushort")
      DllCall("RtlMoveMemory", "ptr", &SOCKADDR_BTH+2, "ptr", numget(numget(WSAQUERYSETW, A_PtrSize*12)+0, A_PtrSize*2)+2, int, 6)   ; lpcsaBuffer.RemoteAddr.lpSockaddr.BLUETOOTH_ADDRESS_STRUCT
      DllCall("ole32\CLSIDFromString", "wstr", "{00000003-0000-1000-8000-00805F9B34FB}", "ptr", &SOCKADDR_BTH+16)   ; RFCOMM
      loop 10
      {
         DllCall("ws2_32\connect", "int", socket, "ptr", &SOCKADDR_BTH, "int", 36)
         sleep 1500
      }
      DllCall("ws2_32\closesocket", "int", socket)
      DllCall("ws2_32\WSALookupServiceEnd", "ptr", lphLookup)
      break
   }
}
msgbox done
exitapp
Last edited by malcev on 24 Mar 2022, 17:47, edited 2 times in total.

hotkeyuser1234
Posts: 92
Joined: 07 Mar 2020, 12:27

Re: Connect to bluetooth headset via shortcut

Post by hotkeyuser1234 » 27 Nov 2020, 14:48

Thank you @malcev !

I tested both of your scripts and unfortunately, both do not work for me. When running script 1, I first see a pop-up: "no found", then another pop-up is shown with "done"

For script 2 I get: "not found"

Is any adjustment of the script necessary to search for the specific headset or can you help me fix the code?

Thank you!

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Connect to bluetooth headset via shortcut

Post by malcev » 27 Nov 2020, 15:25

Yo should put there name of Your device

Code: Select all

deviceName := "jbl clip 3"

hotkeyuser1234
Posts: 92
Joined: 07 Mar 2020, 12:27

Re: Connect to bluetooth headset via shortcut

Post by hotkeyuser1234 » 22 Dec 2020, 06:54

Thank you very much for your help! It works now:)

gsf81
Posts: 5
Joined: 20 Jul 2021, 13:52

Re: Connect to bluetooth headset via shortcut

Post by gsf81 » 20 Jul 2021, 13:58

malcev wrote:
24 Nov 2020, 22:52
Found time to read about this api.
https://docs.microsoft.com/en-us/windows/win32/api/_bluetooth/
It does not really connects, but enable/disable bluetooth services for device - therefore connects/disconnects it.
The same api uses btcom I think.
Connection can be done like this

...
Sorry to revive a very old thread/post, I'm having trouble disconnecting a bluetooth device using this script and I have tried fiddling around with it to no avail. Would you mind helping me with it? I haven't found any leads anywhere else.

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Connect to bluetooth headset via shortcut

Post by malcev » 20 Jul 2021, 14:51

If You need disconnect, try to change this

Code: Select all

toggle := toggleOn := 1
to this

Code: Select all

toggle := toggleOn := 0
Now cannot test it by myself.

gsf81
Posts: 5
Joined: 20 Jul 2021, 13:52

Re: Connect to bluetooth headset via shortcut

Post by gsf81 » 20 Jul 2021, 15:27

malcev wrote:
20 Jul 2021, 14:51
If You need disconnect, try to change this
...
That's actually exactly what I tried but it didn't end up disconnecting. The connecting script worked for me for connections.
I also tried to modify your winsock script but to no avail.

Thanks for your help regardless though! I scripted a gui based solution that should work for now.

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Connect to bluetooth headset via shortcut

Post by malcev » 20 Jul 2021, 18:21

It works for me like this:

Code: Select all

deviceName := "jbl clip 3"

DllCall("LoadLibrary", "str", "Bthprops.cpl", "ptr")
VarSetCapacity(BLUETOOTH_DEVICE_SEARCH_PARAMS, 24+A_PtrSize*2, 0)
NumPut(24+A_PtrSize*2, BLUETOOTH_DEVICE_SEARCH_PARAMS, 0, "uint")
NumPut(1, BLUETOOTH_DEVICE_SEARCH_PARAMS, 4, "uint")   ; fReturnAuthenticated
VarSetCapacity(BLUETOOTH_DEVICE_INFO, 560, 0)
NumPut(560, BLUETOOTH_DEVICE_INFO, 0, "uint")
loop
{
   If (A_Index = 1)
   {
      foundedDevice := DllCall("Bthprops.cpl\BluetoothFindFirstDevice", "ptr", &BLUETOOTH_DEVICE_SEARCH_PARAMS, "ptr", &BLUETOOTH_DEVICE_INFO, "ptr")
      if !foundedDevice
      {
         msgbox no bluetooth devices
         return
      }
   }
   else
   {
      if !DllCall("Bthprops.cpl\BluetoothFindNextDevice", "ptr", foundedDevice, "ptr", &BLUETOOTH_DEVICE_INFO)
      {
         msgbox no found
         break
      }
   }
   if (StrGet(&BLUETOOTH_DEVICE_INFO+64) = deviceName)
   {
      VarSetCapacity(Handsfree, 16)
      DllCall("ole32\CLSIDFromString", "wstr", "{0000111e-0000-1000-8000-00805f9b34fb}", "ptr", &Handsfree)   ; https://www.bluetooth.com/specifications/assigned-numbers/service-discovery/
      VarSetCapacity(AudioSink, 16)
      DllCall("ole32\CLSIDFromString", "wstr", "{0000110b-0000-1000-8000-00805f9b34fb}", "ptr", &AudioSink)
      hr1 := DllCall("Bthprops.cpl\BluetoothSetServiceState", "ptr", 0, "ptr", &BLUETOOTH_DEVICE_INFO, "ptr", &Handsfree, "int", 0)   ; voice
      hr2 := DllCall("Bthprops.cpl\BluetoothSetServiceState", "ptr", 0, "ptr", &BLUETOOTH_DEVICE_INFO, "ptr", &AudioSink, "int", 0)   ; music
      if (hr1 = 0) and (hr2 = 0)
         break
      else
      {
         DllCall("Bthprops.cpl\BluetoothSetServiceState", "ptr", 0, "ptr", &BLUETOOTH_DEVICE_INFO, "ptr", &Handsfree, "int", 1)   ; voice
         DllCall("Bthprops.cpl\BluetoothSetServiceState", "ptr", 0, "ptr", &BLUETOOTH_DEVICE_INFO, "ptr", &AudioSink, "int", 1)   ; music
         DllCall("Bthprops.cpl\BluetoothSetServiceState", "ptr", 0, "ptr", &BLUETOOTH_DEVICE_INFO, "ptr", &Handsfree, "int", 0)   ; voice
         DllCall("Bthprops.cpl\BluetoothSetServiceState", "ptr", 0, "ptr", &BLUETOOTH_DEVICE_INFO, "ptr", &AudioSink, "int", 0)   ; music
         break
      }
   }
}
DllCall("Bthprops.cpl\BluetoothFindDeviceClose", "ptr", foundedDevice)
msgbox done
ExitApp
Last edited by malcev on 24 Mar 2022, 17:47, edited 1 time in total.

gsf81
Posts: 5
Joined: 20 Jul 2021, 13:52

Re: Connect to bluetooth headset via shortcut

Post by gsf81 » 20 Jul 2021, 18:59

malcev wrote:
20 Jul 2021, 18:21
It works for me like this:
...
I used the same code (after changing the headphone's name of course) and the code says done but my headphones remain connected. I am on Windows 11 fwiw so I'm not sure if that broke something but the connection script still works so I don't see why not

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Connect to bluetooth headset via shortcut

Post by malcev » 20 Jul 2021, 19:05

code says done but my headphones remain connected
Do You mean that You continue hear sound from headphones?

gsf81
Posts: 5
Joined: 20 Jul 2021, 13:52

Re: Connect to bluetooth headset via shortcut

Post by gsf81 » 20 Jul 2021, 19:12

malcev wrote:
20 Jul 2021, 19:05
code says done but my headphones remain connected
Do You mean that You continue hear sound from headphones?
Yes, and I can't connect to them from other devices

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Connect to bluetooth headset via shortcut

Post by malcev » 20 Jul 2021, 19:45

This script just turns on and turns off Handsfree and audio sink services for bluetooth device.
So You need to see which services are used by Your device, turn off them manually and check if it disables sound.
If You can disable them manually then You need to test does script disables them.
Also check errors for BluetoothSetServiceState dllcalls.

Post Reply

Return to “Ask for Help (v1)”