FromBluetoothAddressAsync永远不会在WPF应用程序中的Windows 10 Creators Update上返回

时间:2017-04-23 06:30:04

标签: c# windows-10 bluetooth-lowenergy

我升级到Windows 10,版本1703 build 15063(Creators Update)正式发布。当我在WPF桌面应用程序中运行以下代码时,BluetoothLEDevice.FromBluetoothAddressAsync永远不会返回。

此代码在我的Windows 10更新(即之前的1607版本14393)之前工作正常。如果它在新的Win 10 1703中作为UWP运行,该代码也可以正常工作。

BluetoothLEAdvertisementWatcher BleWatcher = null;

private void Button_Click(object sender, RoutedEventArgs e)
{
     BleWatcher = new BluetoothLEAdvertisementWatcher
     {
          ScanningMode = BluetoothLEScanningMode.Active
     };
     BleWatcher.Received += Watcher_Received;
     BleWatcher.Start();
}

private async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, 
                                    BluetoothLEAdvertisementReceivedEventArgs args)
{
         var device = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
         // never continues beyond this point above with my BTLE devices that previously worked 
}

我按照https://stackoverflow.com/a/37335251/3187714中的说明设置我的WPF桌面应用程序以使用UWP API。

问题更严重,因为我的现有WPF应用程序将在客户开始升级到Win 10 1703时被破坏,因为我现有的exe不再有效。

是否有其他人在(非UWP)桌面版exe中使用Windows 10 1703更新遇到此问题?

经过进一步的实验,我确实发现如果我将可选的BluetoothAddressType.Public第二个参数添加到FromBluetoothAddressAsync调用中,则返回该函数,但返回的设备为null。

var device = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress, BluetoothAddressType.Public);

3 个答案:

答案 0 :(得分:4)

看起来15063中蓝牙API周围的安全功能存在一个导致此问题的错误(我看到同样的事情)。看看这个主题:

https://social.msdn.microsoft.com/Forums/en-US/58da3fdb-a0e1-4161-8af3-778b6839f4e1/bluetooth-bluetoothledevicefromidasync-does-not-complete-on-10015063?forum=wdk#ef927009-676c-47bb-8201-8a80d2323a7f

tl; dr对于C ++应用程序,它们提供了一个CoInitializeSecurity函数来调用。对于其他人来说,看起来他们建议创建一个AppId 在注册表中,因为P / Invoke并不是很有趣。

奇怪的是,目前通过noble-uwp为我工作正常,它使用C ++绑定到UWP函数以通过node.js进行访问。只有通过C#我才会遇到问题,并且根据我是否在UWP或WPF / Console / Desktop应用程序中,事情会在不同的点上失败。

在论坛帖子中概述将AppId添加到注册表之后,事情再次对我有用。

答案 1 :(得分:0)

有趣的是, 使用cppwinrt 在桌面应用程序上工作

Advertisement::BluetoothLEAdvertisementWatcher watcher;

void Start() {
    watcher.ScanningMode(Advertisement::BluetoothLEScanningMode::Active);
    Windows::Foundation::TimeSpan timeout = std::chrono::seconds(2);
    watcher.SignalStrengthFilter().OutOfRangeTimeout(timeout);
    watcher.SignalStrengthFilter().OutOfRangeThresholdInDBm(-90);

    watcher.Received([&](Advertisement::BluetoothLEAdvertisementWatcher watcher, Advertisement::BluetoothLEAdvertisementReceivedEventArgs eventArgs) {
        connect(eventArgs.BluetoothAddress());
    });
    watcher.Start();
}

Windows::Foundation::IAsyncAction connect(uint64_t uuid) {
    co_await resume_background();
    BluetoothLEDevice device = co_await BluetoothLEDevice::FromBluetoothAddressAsync(uuid);
    GenericAttributeProfile::GattDeviceServicesResult gatt = co_await device.GetGattServicesForUuidAsync(myServiceUUID);
    // works fine!
}

然而,关于GATT特征的通知在此之后对我不起作用。 I have filed a bug report与cppwinrt项目有关,但开发者似乎并不特别倾向于调查它。

我不知道该API的作用与桌面C#版本不同。

答案 2 :(得分:0)

如果您希望在VB中使用CoInitializeSecurity解决方案,这里有一个pinvoke解决方案。请记住取消/修理所有BLE设备!

请注意,必须是代码中执行的第一件事。 请注意,这并非完全安全。

Opacitymask