This test with BluetoothSelectDevices works on my OS (Windows 10 22H2), except for the Callback (not really needed...) :
Dim bsdp As BLUETOOTH_SELECT_DEVICE_PARAMS = New BLUETOOTH_SELECT_DEVICE_PARAMS()
bsdp.dwSize = Marshal.SizeOf(GetType(BLUETOOTH_SELECT_DEVICE_PARAMS))
bsdp.hwndParent = Me.Handle
'bsdp.pszInfo = "Information"
bsdp.fShowAuthenticated = True
bsdp.fShowUnknown = True
bsdp.fShowRemembered = True
'bsdp.fAddNewDeviceWizard = True
DeviceCallbackProc = New PfnDeviceCallback(AddressOf DeviceCallback)
bsdp.pfnDeviceCallback = DeviceCallbackProc
Dim bRet = BluetoothSelectDevices(bsdp)
If (bRet) Then
' Assuming 1 device is returned
Dim pDevices As New BLUETOOTH_DEVICE_INFO()
pDevices = CType(Marshal.PtrToStructure(bsdp.pDevices, pDevices.GetType()), BLUETOOTH_DEVICE_INFO)
' sAddress = "8C:D1:7B:BC:30:30"
Dim sAddress = String.Join(":", BitConverter.GetBytes(pDevices.Address).Take(6).Reverse().[Select](Function(b) b.ToString("X2")))
Dim sName = pDevices.szName
' ex : COD_MAJOR_PHONE and COD_PHONE_MINOR_SMART : see bthdef.h for all codes
Dim nCODMajor = GET_COD_MAJOR(pDevices.ulClassofDevice)
Dim nCODMinor = GET_COD_MINOR(pDevices.ulClassofDevice)
BluetoothSelectDevicesFree(bsdp)
End If
With Declarations :
<DllImport("Bthprops.cpl", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function BluetoothSelectDevices(ByRef pbtsdp As BLUETOOTH_SELECT_DEVICE_PARAMS) As Boolean
End Function
<DllImport("Bthprops.cpl", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function BluetoothSelectDevicesFree(ByRef pbtsdp As BLUETOOTH_SELECT_DEVICE_PARAMS) As Boolean
End Function
Public Delegate Function PfnDeviceCallback(pvParam As IntPtr, ByRef pDevice As BLUETOOTH_DEVICE_INFO) As Boolean
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure BLUETOOTH_SELECT_DEVICE_PARAMS
Public dwSize As Integer
Public cNumOfClasses As Integer
Public prgClassOfDevices As IntPtr
Public pszInfo As String
Public hwndParent As IntPtr
Public fForceAuthentication As Boolean
Public fShowAuthenticated As Boolean
Public fShowRemembered As Boolean
Public fShowUnknown As Boolean
Public fAddNewDeviceWizard As Boolean
Public fSkipServicesPage As Boolean
Public pfnDeviceCallback As PfnDeviceCallback 'PFN_DEVICE_CALLBACK
Public pvParam As IntPtr
Public cNumDevices As Integer
Public pDevices As IntPtr
Public ReadOnly Property Devices As BLUETOOTH_DEVICE_INFO()
Get
If cNumDevices > 0 Then
Dim devs = New BLUETOOTH_DEVICE_INFO(cNumDevices - 1) {}
For idevice = 0 To cNumDevices - 1
devs(idevice) = CType(Marshal.PtrToStructure(New IntPtr(pDevices.ToInt64() + idevice * Marshal.SizeOf(GetType(BLUETOOTH_DEVICE_INFO))), GetType(BLUETOOTH_DEVICE_INFO)), BLUETOOTH_DEVICE_INFO)
Next
Return devs
End If
Return New BLUETOOTH_DEVICE_INFO(-1) {}
End Get
End Property
Public ReadOnly Property Device As BLUETOOTH_DEVICE_INFO
Get
If cNumDevices > 0 Then
Dim lDevice As BLUETOOTH_DEVICE_INFO = Marshal.PtrToStructure(pDevices, GetType(BLUETOOTH_DEVICE_INFO))
Return lDevice
End If
Return New BLUETOOTH_DEVICE_INFO()
End Get
End Property
End Structure
<StructLayout(LayoutKind.Sequential)>
Structure SYSTEMTIME
Public wYear As UShort
Public wMonth As UShort
Public wDayOfWeek As UShort
Public wDay As UShort
Public wHour As UShort
Public wMinute As UShort
Public wSecond As UShort
Public wMilliseconds As UShort
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure BLUETOOTH_DEVICE_INFO
Public dwSize As UInteger
Public Address As ULong
Public ulClassofDevice As UInteger
Public fConnected As Boolean
Public fRemembered As Boolean
Public fAuthenticated As Boolean
Public stLastSeen As SYSTEMTIME
Public stLastUsed As SYSTEMTIME
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=248)>
Public szName As String
End Structure
Public COD_FORMAT_BIT_OFFSET = (0)
Public COD_MINOR_BIT_OFFSET = (2)
Public COD_MAJOR_BIT_OFFSET = (8 * 1)
Public COD_SERVICE_BIT_OFFSET = (8 * 1 + 5)
Public COD_FORMAT_MASK = (&H3)
Public COD_MINOR_MASK = (&HFC)
Public COD_MAJOR_MASK = (&H1F00)
Public COD_SERVICE_MASK = (&HFFE000)
Public Function GET_COD_FORMAT(_cod As UInteger)
Return ((_cod And COD_FORMAT_MASK) >> COD_FORMAT_BIT_OFFSET)
End Function
Public Function GET_COD_MINOR(_cod As UInteger)
Return ((_cod And COD_MINOR_MASK) >> COD_MINOR_BIT_OFFSET)
End Function
Public Function GET_COD_MAJOR(_cod As UInteger)
Return ((_cod And COD_MAJOR_MASK) >> COD_MAJOR_BIT_OFFSET)
End Function
Public Function GET_COD_SERVICE(_cod As UInteger)
Return ((_cod And COD_SERVICE_MASK) >> COD_SERVICE_BIT_OFFSET)
End Function
Public Shared DeviceCallbackProc As PfnDeviceCallback = Nothing
Public Shared Function DeviceCallback(pvParam As IntPtr, ByRef pDevice As BLUETOOTH_DEVICE_INFO) As Boolean
' Never reached...
Return True
End Function