繁体   English   中英

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

[英]FromBluetoothAddressAsync never returns on Windows 10 Creators Update in WPF Application

我升级到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);

看起来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添加到注册表后,事情再次对我有用。

有趣的是, 使用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特征的通知在此之后对我不起作用。 我已经向 cppwinrt项目提交了一份错误报告 ,但开发人员似乎并不特别倾向于调查它。

我不知道那个API与桌面C#版本有什么不同。

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

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

Public Enum RpcAuthnLevel
    Default1 = 0
    None = 1
    Connect = 2
    Call1 = 3
    Pkt = 4
    PktIntegrity = 5
    PktPrivacy = 6
End Enum

Public Enum RpcImpLevel
    Default1 = 0
    Anonymous = 1
    Identify = 2
    Impersonate = 3
    Delegate1 = 4
End Enum

Public Enum EoAuthnCap
    None = &H0
    MutualAuth = &H1
    StaticCloaking = &H20
    DynamicCloaking = &H40
    AnyAuthority = &H80
    MakeFullSIC = &H100
    Default1 = &H800
    SecureRefs = &H2
    AccessControl = &H4
    AppID = &H8
    Dynamic = &H10
    RequireFullSIC = &H200
    AutoImpersonate = &H400
    NoCustomMarshal = &H2000
    DisableAAA = &H1000
End Enum

Declare Function CoInitializeSecurity Lib "ole32.dll" (pVoid As IntPtr, cAuthSvc As Integer, asAuthSvc As IntPtr, pReserved1 As IntPtr, dwAuthnLevel As Integer, dwImpLevel As Integer, pAuthList As IntPtr, dwCapabilities As Integer, pReserved3 As IntPtr) As Integer

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero, IntPtr.Zero, RpcAuthnLevel.Default1, RpcImpLevel.Identify, IntPtr.Zero, EoAuthnCap.None, IntPtr.Zero)
    'Other code
End Sub

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM