Laden...

Bluetoothgeräte listen, ohne UWP

Erstellt von Fabiano vor 2 Jahren Letzter Beitrag vor 2 Jahren 422 Views
F
Fabiano Themenstarter:in
27 Beiträge seit 2021
vor 2 Jahren
Bluetoothgeräte listen, ohne UWP

Hallo Leute!

Ich möchte eine WPF-Applikation erstellen, in der alle BT-Geräte zur Auswahl angezeigt werden. Leider fliegt auf Google/StackOverflow viel verschiedener Code rum, und tatsächlich schlagen auch auf Anhieb beide von mir versuchten Ansätze fehl. Es werden keine BT-Geräte zurückgegeben, obwohl das Betriebssystem sehr wohl welche findet.

Der erste Versuch:

BTTests.ThirtyTwoFeetNET.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFrameworks>net48</TargetFrameworks>
    <UseWPF>true</UseWPF>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="32feet.NET" Version="3.5.0" />
  </ItemGroup>

</Project>

MainWindow.xaml.cs

using InTheHand.Net.Sockets;
using System.Windows;

namespace BTTests.ThirtyTwoFeetNET
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            using (var client = new BluetoothClient()) {
                foreach (var device in client.DiscoverDevicesInRange()) {
                    MessageBox.Show(device.DeviceName);
                }
            }
        }
    }
}

Und der zweite:

BTTests.MWSC.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFrameworks>net48</TargetFrameworks>
    <UseWPF>true</UseWPF>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.19041.1" />
  </ItemGroup>

</Project>

MainWindow.xaml.cs

using System.Windows;
using Windows.Devices.Enumeration;

namespace BTTests.MWSC
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var picker = new DevicePicker();
            picker.Show(new Windows.Foundation.Rect(Left, Top, Width, Height));
        }
    }
}

Hat hier jemand sowas am Laufen? Oder komme ich um eine UWP nicht herum?
UWP möchte ich eigentlich vermeiden, da ich bisher mit WPF arbeite.
Der Einfachheit halber habe ich auch noch die VS Solution angehängt.

Vielen Dank für eure Hilfe!

Information von MrSparkle vor 2 Jahren

Dateianhang entfernt. Bitte poste relevanten Code im Beitrag. Siehe [Hinweis] Wie poste ich richtig?, Punkt 4.1

16.834 Beiträge seit 2008
vor 2 Jahren

Die 32Feet Lib (Legacy) bzw. die Nachfolgerlibs (InTheHand.Net.*) vom gleichen Macher sind weit verbreitet und eigentlich auch sehr gut.

Ich persönlich nutze die Libs mit .NET Core auf Windows wie auch auf meinem Raspberry und hab keine Probleme Devices zu finden.
Mein BT Kopfhörer wird einwandfrei gefunden und mein Smart Home Zeugs auch. Hab die Libs auch im produktiven Einsatz bei Kunden im Maschinenbausektor.


static void Main(string[] args)
{
    BluetoothClient client = new BluetoothClient();

    Console.WriteLine("Discovering..");
    IReadOnlyCollection<BluetoothDeviceInfo> devices = client.DiscoverDevices();

    Console.WriteLine("Listing:");
    foreach (BluetoothDeviceInfo d in devices)
    {
        Console.WriteLine("Device: " + d.DeviceName);
    }

    Console.WriteLine("Finished.");
    Console.ReadKey();
}

Du verwendest DiscoverDevicesInRange, was für den Discover-Mode gedacht ist, nicht für Listings.
Steht auch relativ deutlich in der Doku 😉

UWP brauchst Du nicht, wieso auch.
Wird ja nur die Win32 API angesprochen.

F
Fabiano Themenstarter:in
27 Beiträge seit 2021
vor 2 Jahren

Hallo Abt!

Vielen Dank für deine Antwort! Es hat mir sehr geholfen, wenn auch indirekt.
Mein Problem war nämlich, dass ich die Methoden für Bluetooth <4 verwendet habe, es sich bei meinen Geräten aber um BluetoothLE (4+) Dinger handelt...😉
Dieser Code funktioniert soweit:

        static void Main(string[] args)
        {
            Console.WriteLine("Discovering...");
            var devices = InTheHand.Bluetooth.Bluetooth.ScanForDevicesAsync().Result;
            Console.WriteLine("Listing...");
            foreach (var device in devices) {
                Console.WriteLine($"\t{device.Name}");
            }
            Console.WriteLine("Finished.");
            Console.ReadKey();
        }

Jetzt möchte ich das Ganze aber noch awaiten und einen Handler jedes Gerät direkt nach den "Finden" in eine ObservableCollection hinzufügen.
Leider scheint Bluetooth.AdvertisementReceived dafür nicht vorgesehen zu sein (jedenfalls wird das Event nie ausgelöst) und ein anderes finde ich nicht.
Hast du irgendeine Idee?

Vielen Dank für deine Hilfe!

Gruss
Fabiano

16.834 Beiträge seit 2008
vor 2 Jahren

.ScanForDevicesAsync().Result;

Hinweis: so verwendet man asynchrone Methoden nicht 😉
.Result ist ein absoluter Pitfall (unterdrückt zB Exceptions). Verwende einfach async/await, wie es gedacht ist.

Wenn Du es unbedingt synchron haben willst, wozu es keinen Grund gibt, dann verwende GetAwaiter().GetResult() aber niemals .Result.

Leider scheint Bluetooth.AdvertisementReceived dafür nicht vorgesehen

AdvertisementReceived ist auch nicht "Finden".

Aber ein kurzer Blick in die Doku sagt Dir, wie es gehen sollte: Asynchronous-Device-Discovery
Daher: einfach mal kurz die Doku lesen, dafür ist sie da. Da haben sich Leute für Zeit genommen, diese zu schreiben 🙂

F
Fabiano Themenstarter:in
27 Beiträge seit 2021
vor 2 Jahren

Sorry wegen dem .Result, das verwende ich in produktivem Code natürlich nicht! 😉

Leider bringt dein Link nichts, weil die Klasse BluetoothComponent Legacy-Code ist (InTheHand.Net.Bluetooth statt InTheHand.Bluetooth).
Aber im Prinzip bräuchte ich genau sowas bei der LE-Library, die jedoch InTheHand.BluetoothLE heisst und nicht InTheHand.Bluetooth.
Weisst du da wie? Leider ist sein Code sehr chaotisch und ich steige nicht so durch.

Vielen Dank für deine Hilfe!

16.834 Beiträge seit 2008
vor 2 Jahren

Der Quellcode ist Open Source. Wenn Du ihn nicht verstehst, dann lade ihn runter und debugge ihn 🙂
Schau einfach in die entsprechende Lib, dann wirst sie auch verstehen.