在 UWP 中获取已知蓝牙设备的 COM 端口名称

Posted

技术标签:

【中文标题】在 UWP 中获取已知蓝牙设备的 COM 端口名称【英文标题】:Getting the COM port name for a known Bluetooth device in UWP 【发布时间】:2017-11-02 15:13:26 【问题描述】:

我正在使用DeviceWatcher 为 UWP 应用中的配对蓝牙设备获取 DeviceInformation。我像这样设置 DeviceWatcher

var requestedProperties = new string[]  "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected" ;
var deviceWatcher = DeviceInformation.CreateWatcher("(System.Devices.Aep.ProtocolId:=\"e0cbf06c-cd8b-4647-bb8a-263b43f0f974\")", requestedProperties, DeviceInformationKind.AssociationEndpoint); // ClassGuid = e0cbf06c-cd8b-4647-bb8a-263b43f0f974 includes all Bluetooth devices
deviceWatcher.Added += DeviceWatcher_Added;
deviceWatcher.Updated += DeviceWatcher_Updated;
deviceWatcher.Start();

当调用 DeviceWatcher_Added 事件处理程序时,我通过检查设备名称来检查设备是否是我感兴趣的设备,以及它是否提供RfcommServiceId.SerialPort.Uuid 服务。

获得蓝牙设备的 DeviceInformation 后,我对如何获取它的 COM 端口感兴趣?我可以在设备管理器中看到它,它被列为“蓝牙链路上的标准串行 (COM8)”,但我看不到如何以编程方式在 UWP 中获取该“COM8”。

我尝试将 DeviceInformation 设置为 SerialDevice,然后我可以得到 SerialDevice.PortName(参见 this 答案)但我对 SerialDevice.FromIdAsync(deviceInfo.Id) 的调用失败并出现 System.Exception: The data is invalid。

(注意,一些诱人的答案,例如 this 和 this,使用 Windows 管理工具 WMI 功能,但这些在 UWP 中不可用。)

【问题讨论】:

如何确保 deviceInfo.Id 是您设备的 id (COM8)?你能显示完整的代码使这个异常:System.Exception: The data is invalid 完整代码是here 鉴于您已经知道deviceInfo.Name,想知道您是否可以从中获得Id(await DeviceInformation.FindAllAsync(SerialDevice.GetDeviceSelector())).Single(di => di.Name == deviceInfo.Name).Id 基于your device info,蓝牙 rfcomm 是正确的方向,但为什么要“SerialDevice.PortName”? 这样我就可以调用依赖它的现有代码库了。 【参考方案1】:

在another question Rita 上建议查看Serial UART sample,它帮助我找到了一种方法。我暂时不会将此标记为答案,因为它似乎过于间接,无法成为规范的方式。

虽然我的 UWP 应用中有配对蓝牙设备的 DeviceInformation,但我还需要 SerialDevices 的列表,以便我可以匹配它们。这是生成的代码。

public async Task<string> ComPort(DeviceInformation deviceInfo)

    var serialDevices = new Dictionary<string, SerialDevice>();
    var serialSelector = SerialDevice.GetDeviceSelector();
    var serialDeviceInformations = (await DeviceInformation.FindAllAsync(serialSelector)).ToList();
    var hostNames = NetworkInformation.GetHostNames().Select(hostName => hostName.DisplayName.ToUpper()).ToList(); // So we can ignore inbuilt ports
    foreach (var serialDeviceInformation in serialDeviceInformations)
    
        if (hostNames.FirstOrDefault(hostName => hostName.StartsWith(serialDeviceInformation.Name.ToUpper())) == null)
        
            try
            
                var serialDevice = await SerialDevice.FromIdAsync(serialDeviceInformation.Id);
                if (serialDevice != null)
                
                    serialDevices.Add(deviceInfo.Id, serialDevice);
                
            
            catch (Exception ex)
            
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            
        
    
    // Example Bluetooth DeviceInfo.Id: "Bluetooth#Bluetooth9c:b6:d0:d6:d7:56-00:07:80:cb:56:6d"
    // from device with Association Endpoint Address: "00:07:80:cb:56:6d"
    var lengthOfTrailingAssociationEndpointAddresss = (2 * 6) + 5;
    var bluetoothDeviceAddress = deviceInfo.Id.Substring(deviceInfo.Id.Length - lengthOfTrailingAssociationEndpointAddresss, lengthOfTrailingAssociationEndpointAddresss).Replace(":", "").ToUpper();
    var matchingKey = serialDevices.Keys.FirstOrDefault(id => id.Contains(bluetoothDeviceAddress));
    if (matchingKey != null)
    
        return serialDevices[matchingKey].PortName;
    
    return "";

【讨论】:

以上是关于在 UWP 中获取已知蓝牙设备的 COM 端口名称的主要内容,如果未能解决你的问题,请参考以下文章

使用蓝牙FTP从已知设备获取文件

UWP蓝牙查找设备耗时较长

如何获取蓝牙配对设备的设备名称?

获取蓝牙低功耗设备的设备句柄

Unity UWP 蓝牙条码扫描器

C# 串口通信