簡體   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