3

UPDATE I now have reason to believe that you can't use Windows Creator on Enterprise LTSB because the version isn't high enough and can't be updated! If someone could confirm this AND state how I should go about developing a Bluetooth app given that I can use Creator it would be much appreciated.

"Could not find Windows Runtime type 'Windows.Devices.Bluetooth.GenericAttributeProfile.GattDeviceServicesResult'"

I developed some sample code on my developer machine to communicate through BLE (Bluetooth Low Energy) in C#/.Net. When I transfer this release folder to another machine and run the program, I get the message above when I try to initiate BLE communications. I'm guessing that I'm missing some key library/dll (or .NETCore or .Net Framework), but what? I've searched and can't find an answer.

A possibly useful clue (or possibly irrelevant) is that that in my project I have a reference to System.Runtime.WindowsRuntime in directory C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETCore\v4.5.1\System.Runtime.WindowsRuntime.dll The other machine does not have a v4.5.1 but only a v4.5. However, when I try and install v4.5.1 I'm told that I already have a newer version! Perhaps someone could tell me how to get .netcore v4.5.1 on a machine?

Thanks, Dave

More information. In the original project, there is a reference "Windows" with path C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.17134.0\Windows.winmd If you use Object Browser on this you'll see Windows.Devices.Bluetooth.GenericAttributeProfile.GattDeviceServicesResult This same file (same version) is also on the system I'm trying to get my code to run on. Not sure why it's not "seeing" it at run time.

Apparently, others have had this problem. See: Bluetooth LE GattDeviceServicesResult TypeLoadException from WPF application

Yet more information based on research I installed Visual Studio on the production machine thinking that would remove one difference between my developer machine and the production machine. Still no luck. However, I will point out that one of the remaining differences is that my developer machine has Windows 10 Pro. The production machine (which is a Tablet) has Windows 10 Enterprise 2016 LTSB

Dave
  • 8,095
  • 14
  • 56
  • 99
  • It seems that you are attempting to use UWP namespaces in a .NET Framework app, https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth You are supposed to only use it in a UWP app, like the sample project https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/BluetoothLE – Lex Li Jul 24 '18 at 19:24
  • Lex. You are correct. I'm using some UWP stuff in a WPF app. However, I've successfully done it on my development machine. I just need to get the app working on a production machine. I'm told you can use Universal app libraries for a regular WPF app. I'll find the references if needed. Thanks for looking! – Dave Jul 24 '18 at 21:31
  • I don't know what kind of references you can find. https://blogs.msdn.microsoft.com/dotnet/2018/05/07/net-core-3-and-support-for-windows-desktop-applications/ Clearly Microsoft only plans to grant access to the full Windows 10 API in .NET Core 3.0 and .NET Framework 4.8. – Lex Li Jul 24 '18 at 21:36
  • Lex, Here's one reference about using BLE in WPF apps. https://stackoverflow.com/questions/37333179/is-there-any-way-to-use-bluetooth-le-from-a-c-sharp-desktop-app-in-windows-10/37335251#37335251 Like I said, I've got it working on my development machine. I suspect I'm just missing a reference or library. – Dave Jul 25 '18 at 15:14
  • 2
    Unless Microsoft says it is **supported**, I won't trust any other. – Lex Li Jul 25 '18 at 15:15
  • 1
    The answer you linked says "Note that the #2 version depends on the version of .Net that you're using.", in UWP the GAC (or bundles it with the exe now maybe?) handles finding the specific installed compatible dll (on the prod machine), in your case you need to explicitly know that location if its going to work at all. You might be able to copy it into a `/lib/` folder and import from there more reliably, but that could cause issues down the road too – Thymine Jul 25 '18 at 19:37
  • Thanks Thymine. However, on both machines System.Runtime.WindowsRuntime.dll is in the directory: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5 Note that I changed to use version 4.5 on my developer machine because I couldn't get 4.5.1 on my production machine and thought that might be the problem. – Dave Jul 25 '18 at 20:18
  • I not have some async methods https://i.imgur.com/VUWKLSB.png – nim Jan 18 '19 at 12:04

1 Answers1

0

It seems that Windows 10 Enterprise does not support quite a few of the methods in Windows.Devices.Bluetooth namespace. The solution that I found for this requires Windows 10 Enterprise users to pair their BLE devices. This allows us to use the obsolete BluetoothLEDevice.GattServices property. We catch the TypeLoadException and fall back to the methods supported in Windows 10 Enterprise.

    private async Task<IReadOnlyCollection<GattDeviceService>> GetGattService(BluetoothLEDevice device, Guid uuid)
    {
        try
        {
            // Try to get the services async first
            return await GetGattServicesAsync(device, uuid);
        }
        catch(TypeLoadException e)
        {
            // Not supported in version of windows. Fall back to old way
            return GetGattDeviceServices(device, uuid);
        }
    }

    private async Task<IReadOnlyList<GattDeviceService>> GetGattServicesAsync(BluetoothLEDevice device, Guid uuid)
    {
        var result = await Device.GetGattServicesForUuidAsync(uuid);
        if(result.Status == GattCommunicationStatus.Success)
        {
            return result.Services;
        }
        return null;
    }

    private IReadOnlyList<GattDeviceService> GetGattDeviceServices(BluetoothLEDevice device, Guid uuid)
    {
        var result = device.GattServices.Where(s => s.Uuid == uuid);
        if(result != null)
        {
            return result.ToList().AsReadOnly();
        }
        return null;
    }

We need to do the same when attempting to get the characteristics from the services. Instead of calling GattDeviceService.GetCharacteristicsForUuidAsync we call GattDeviceService.GetAllCharacteristics(). I also found instances where some PCs did not support any of the BluetoothLEDevice.GetDeviceSelector() methods, which was causing problems creating the watcher. Having to pair the device is a bit of an inconvenience. Unfortunately I have not been able to find any documentation on this. Other than a couple videos here where they discuss not having to pair BLE devices anymore which led me to believe that it was not supported in LTSB.

Tim
  • 1
  • 1