Introduction

Recently I had an idea of a project which requires using the Bluetooth API. I wanted to create something simple and did not want to use UWP for 2 reasons:

  1. I wanted to have a tray icon. This is also possible with UWP but creating a full-trust application seemed way more complicated for my scenario.
  2. I wanted a simple self-contained application which can run without the need of enabling developer mode for the end users.

How to Use BLE Classes with WPF

My framework of choice for the project was WPF. There was only 1 problem, the BLE classes were not available. After a lot of research and failed attempts there is actually a way to use them with WPF. Here is what I did:

1. Install Windows SDK

First thing first you have to install the Windows SDK. Ideally you want to install it in its default location since you cannot change it later. Believe me I’ve tried!

If you installed it in a different location, you cannot use it with UWP and the Visual Studio for creating for example Full-Trust applications. I’ve also tried that one too.

The SDK will give you the Windows.winmd file. If you want to learn more check out How to read a winmd (WinRT metadata file). Ian Boyd explained it in great detail. There is also the official documentation

2. Locate Windows.winmd File and Add a Reference

If you followed the default location path the Windows.winmd file is located in C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.19041.0\Windows.winmd. You can go ahead and аdd this file as a reference to your project.

Unfortunately, for me this does not work with .NET5. I tried so many things that if I should write them, I have to make another blog post. For this example and for my project I am using .Net Core 3.1.

Now you can use the BLE classes with your WPF, Windows Forms, and/or Console applications. There is one catch though. You cannot use async await yet.

3. Fix Async methods

In order to use them you have to bring System.Runtime.WindowsRuntime.dll too. If you installed .NET Framework 4 you should have it in your machine. My file’s location is C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Runtime.WindowsRuntime.dll

After all of this, you should have a working application.

Let’s Create a BLE Application

For the sake of simplicity, we will create a console application.

Create a .NET Core 3.1 Console application. Let’s call it BleConsoleDemo. We will write a simple program that catches all the BLE devices that emits advertising packets.

Do not forget to add System.Runtime.WindowsRuntime.dll and Windows.winmd references as described above.

class Program
{
    static async Task Main(string[] args)
    {
        var watcher = new BluetoothLEAdvertisementWatcher();
        watcher = new BluetoothLEAdvertisementWatcher()
        {
            ScanningMode = BluetoothLEScanningMode.Passive
        };

        watcher.Received += Watcher_Received;
        watcher.Start();

        await Task.Delay(Timeout.Infinite);
    }

    private static async void Watcher_Received(
        BluetoothLEAdvertisementWatcher sender,
        BluetoothLEAdvertisementReceivedEventArgs args)
    {
        var device = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
        if (device != null)
        {
            Console.WriteLine(device.BluetoothAddress);
        }
    }
}

You can find the example pfoject in my github.

Conclusion

In this blog post managed to use the Bluetooth API from projects other than UWP. Even though it does not work with .NET5, I am satisfied with .NET Core 3.1 too. I would love to see if someone made the BLE work with .NET 5.