如何使用 C# 在 WinForm 中手动绑定到蓝牙低功耗设备?

     2023-03-05     294

关键词:

【中文标题】如何使用 C# 在 WinForm 中手动绑定到蓝牙低功耗设备?【英文标题】:How to Bind manually to a BlueTooth Low Energy Device in a WinForm using C#? 【发布时间】:2017-01-01 23:54:47 【问题描述】:

这个问题的回答者大多是:Windows UWP connect to BLE device after discovery

目前,我正在编写自定义服务并进行测试,使用 Windows 10 上的 C#.NET WinForm 连接到蓝牙低功耗 (BLE) 设备。我正在使用框架 4.6.1。我们使用TI SmartRF06 Evaluation Board 和TI CC2650 BLE 子卡。另一位开发人员正在处理主板的固件。

目前使用类似于参考答案above 的方法,我能够连接到已经绑定的 BLE 设备。此设备是手动绑定的,Windows 确实要求我输入 PIN。由于设备没有 PIN,只需输入“0”即可连接设备。以这种方式连接后,我可以访问所有 GATT 服务并做我需要做的事情。因此,我在查找和获取广告 BLE 设备方面没有任何问题。

问题是如何连接到尚未配对的 BLE 设备?我浏览了网络并找到了许多 BLE 代码示例,但没有具体说明代码中的配对是如何完成的。不确定我什至需要它来配对,但 Windows 似乎只在配对设备上显示我的 GATT 服务。

当我使用未配对的设备执行此操作时:

private void BleWatcherOnReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
       
    var dev = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
    // dev.DeviceInformation.Pairing.CanPair is true
    // dpr.Status is Failed
    DevicePairingResult dpr = await dev.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.None);
    var service = await GattDeviceService.FromIdAsync(dev.DeviceInformation.Id);

设备未手动配对时,dpr 的结果总是失败。这导致GattDeviceServices 为空。但我可以得到 BLE 设备的广告和属性。

也有这种连接方式,但是不知道怎么用:

var prslt = await device.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.ProvidePin, DevicePairingProtectionLevel.None,IDevicePairingSettings);

IdeviceParingSettings 是一个接口。不确定要使用什么类。我在想这是我可以设置我可能需要的“O”的 PIN 码的地方吗?

有没有人在 Windows 中使用 C# 与 BLE 设备配对成功,而 BLE 设备没有安全性。基本上它应该是敞开的。我觉得我错过了一些简单的东西,或者这根本不可能(我已经看到一些帖子声称是这种情况。其中大多数都是多年前的)。

我确实尝试了上述帖子中描述的方法,结果没有任何差异。

感谢任何帮助。如果您需要更多代码,请查看我在顶部提供的链接,因为这是我开始的。如果有可能我做的序列不合适,我会很乐意提供我所有的实际代码。

【问题讨论】:

我包含了数据表链接。如果这些不正确,如果你能修复它们会很棒。 【参考方案1】:

我想通了。我是在正确的轨道上。

连接后使用:

var dev = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);

您需要进行自定义配对:

var prslt = await device.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.ProvidePin, DevicePairingProtectionLevel.None);

但这只会给你一个错误。您还必须创建一个device.DeviceInformation.Pairing.Custom.PairingRequested 事件处理程序。

所以我创建了这个处理程序:

private void handlerPairingReq(DeviceInformationCustomPairing CP, DevicePairingRequestedEventArgs DPR)
        
            //so we get here for custom pairing request.
            //this is the magic place where your pin goes.
            //my device actually does not require a pin but
            //windows requires at least a "0".  So this solved 
            //it.  This does not pull up the Windows UI either.
            DPR.Accept("0");



在 PairAsync 调用之前将其连接起来喜欢:

device.DeviceInformation.Pairing.Custom.PairingRequested += handlerPairingRequested;

完成我的连接的BlueToothAdvertisementWatcher 代码的示例代码:

    private BluetoothLEAdvertisementWatcher BTWatch = new BluetoothLEAdvertisementWatcher();

    private void Inits() 
        
           BTWatch.Received += new TypedEventHandler<BluetoothLEAdvertisementWatcher, BluetoothLEAdvertisementReceivedEventArgs>(BtAddRx);
           BTWatch.Start();
        

    private async void BtAddRx(BluetoothLEAdvertisementWatcher bw, BluetoothLEAdvertisementReceivedEventArgs args)
        
            GattCommunicationStatus srslt;
            GattReadResult rslt;
            bw.Stop();//Stop this while inside.

            device = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
                if (device.DeviceInformation.Pairing.IsPaired == false)
                   

                    /* Optional Below - Some examples say use FromIdAsync
                    to get the device. I don't think that it matters.   */            
                    var did = device.DeviceInformation.Id; //I reuse did to reload later.
                    device.Dispose();
                    device = null;
                    device = await BluetoothLEDevice.FromIdAsync(did);
                    /* end optional */
                    var handlerPairingRequested = new TypedEventHandler<DeviceInformationCustomPairing, DevicePairingRequestedEventArgs>(handlerPairingReq);
                    device.DeviceInformation.Pairing.Custom.PairingRequested += handlerPairingRequested;
                    log("Pairing to device now...."); 

                    var prslt = await device.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.ProvidePin, DevicePairingProtectionLevel.None);                  
                    log("Custom PAIR complete status: " + prslt.Status.ToString() + " Connection Status: " + device.ConnectionStatus.ToString());

                    device.DeviceInformation.Pairing.Custom.PairingRequested -= handlerPairingRequested; //Don't need it anymore once paired.


                    if (prslt.Status != DevicePairingResultStatus.Paired)
                     //This should not happen. If so we exit to try again.
                        log("prslt exiting.  prslt.status=" + prslt.Status.ToString());// so the status may have updated.  lets drop out of here and get the device again.  should be paired the 2nd time around?
                        bw.Start();//restart this watcher.
                        return;
                    
                    else
                    
                        // The pairing takes some time to complete. If you don't wait you may have issues. 5 seconds seems to do the trick.

                        System.Threading.Thread.Sleep(5000); //try 5 second lay.
                        device.Dispose();
                       //Reload device so that the GATT services are there. This is why we wait.                     
                       device = await BluetoothLEDevice.FromIdAsync(did);

                    
 var services = device.GattServices;
//then more code to finish it up.

如果您想断开连接,请使用:

await device.DeviceInformation.Pairing.UnpairAsync();

抱歉,代码混乱。如果有人发现有用或有疑问,请告诉我。我在任何地方都找不到此代码的任何 WinForm 示例。实际上我找不到任何代码来显示如何在没有 UI 的情况下与 PIN 配对。所以我希望这可以帮助任何可能陷入困境的人。

【讨论】:

在github.com/Microsoft/Windows-universal-samples/tree/master/…查看场景8和9 谢谢 - 我找到了这样的例子。正在寻找更多窗口形式和更直接的东西。这些信息似乎真的被埋没了。 @MichaelFrederick 帮了大忙,谢谢!不过,我的实施存在一个问题。已配对的设备不会显示在 Windows UI 中(例如,如果您想在没有我的应用的情况下取消配对)。你有问题吗? 这方面仍有问题。我可以启动观察程序,找到设备,通过 await BluetoothLEDevice.FromBluetoothAddressAsync(addres) 但未调用 handlerPairingReq,因此配对失败。我按照你的说法添加了它,但它对我不起作用:( @MichaelFrederick 你的代码对我帮助很大,谢谢

将 DataGridView 与 FK(主从架构)绑定,但允许在 VS 编辑器中自定义列(C# - Winform)

...FK(主从架构)绑定,但允许在VS编辑器中自定义列(C#-Winform)【英文标题】:BindDataGridViewwithFK(Master-Slavearchitecture),butallowingcolumncustomizationatVSEditor(C#-Winform)【发布时间】:2021-11-2600:18:53【问题描述】:DB中的DataModel实现了主从架... 查看详情

c#,winform绑定实体框架(entityframework)的实体,如何去掉或隐藏导航属性?

以Northwind数据库为例,要绑定的是Employees表,但是因为它与Order表有外键关系,所以在绑定到Datagridview的时候,后面Order这样的列,这是不希望看到的,有什么办法可以去掉或者隐藏?要求是不用手动去设置每一个字段。参考技... 查看详情

如何在c#的winform中制作饼状图和柱状图

使用MSChart控件可以制作出饼图和柱状图1)在Winform中添加Chart控件2)制作饼图请参考:C#使用MsChart实现饼图【链接】http://blog.csdn.net/lzxue1989/article/details/96156233)制作柱状图与2)类似,只要修改一个语句// this.ct_coll.Series["... 查看详情

winform中的datagridview的属性columns中手动添加列后,怎么绑定数据库的数据源,语句怎么写

你直接在数据源的地方作处理,加一个列比如:selecta.*,b.Namefromainnerjoinbona.Aid=b.Bid这样,然后在columns里直接绑定Name,然后整个的datagridview的datasource就等于这段sql对应的dataset/datatable等就行的。参考技术A可以使用Bind属性进行绑定... 查看详情

如何使用 C# 连接到 Winform 应用程序中的 .sdf 文件?

】如何使用C#连接到Winform应用程序中的.sdf文件?【英文标题】:Howtoconnectto.sdffileinWinformapplicationusingC#?【发布时间】:2013-06-0411:30:06【问题描述】:我正在尝试将.sdf文件与我的winform连接。这就是我想要做的:SqlConnectioncon=newSqlCo... 查看详情

如何在 Blazor 项目中使用 C# 绑定制作 HTML 文本多行?

】如何在Blazor项目中使用C#绑定制作HTML文本多行?【英文标题】:HowtomakeaHTMLtextmultilineusingaC#bindinablazorproject?【发布时间】:2020-02-1721:39:52【问题描述】:我有一个带有客户端Razor页面的Blazor项目。在该页面上,我想显示多行文... 查看详情

如何从另一个 WinForm 中通过 C# WinForm 查看

】如何从另一个WinForm中通过C#WinForm查看【英文标题】:HowtoviewthroughC#WinFormfromanotherWinForm【发布时间】:2013-04-1115:26:36【问题描述】:我在C#中使用winforms制作了一个捕获应用程序。我正在尝试从另一个winform中查看一个winform。我... 查看详情

[C#]如何在winform的矩阵单元格中填充颜色?

】[C#]如何在winform的矩阵单元格中填充颜色?【英文标题】:[C#]howtofillcolorsincellofamatrixinwinform?【发布时间】:2021-12-2812:29:14【问题描述】:伙计们我已经编码用4种颜色填充1个单元格。enterimagedescriptionhere单击其中一个时,如何... 查看详情

如何在winform c#中禁用按钮时将焦点设置在按钮上?

】如何在winformc#中禁用按钮时将焦点设置在按钮上?【英文标题】:Howtosetfocusonbuttonwhilebuttonisdisabledinwinformc#?【发布时间】:2021-05-2120:36:02【问题描述】:我想在Windows窗体应用程序中禁用按钮时在按钮中设置焦点。有没有办法... 查看详情

如何在 C# WinForm 桌面应用程序中存储 MySql 数据库连接字符串

】如何在C#WinForm桌面应用程序中存储MySql数据库连接字符串【英文标题】:HowtostoreMySqldatabaseconnectionstringinC#WinFromdesktopapplication【发布时间】:2019-08-2201:31:38【问题描述】:在代码中使用server、user、password和database数据似乎不正确... 查看详情

如何在 C#(Winform)中仅使用鼠标制作多选列表框?

】如何在C#(Winform)中仅使用鼠标制作多选列表框?【英文标题】:HowtomakemultiselectlistboxonlywithmouseinC#(Winform)?【发布时间】:2015-03-2611:03:09【问题描述】:我有listbox里面有一些东西,我在找这个:总是以前的项目保持选中状态... 查看详情

c#的winform程序中,radiobutton的用法

我在窗体上放了三个radiobutton。还有一个combobox。我想在分别选择三个不同的radiobutton时,让combobox绑定不同的数据字段。显示不同的内容。但在运行的时候,点第一个radiobutton时,程序正常运行。当点第二个的radiobutton的时候,就... 查看详情

c#在winform中使用webkit传递js对象实现与网页交互的方法

这篇文章主要介绍了C#在WinForm中使用WebKit传递js对象实现与网页交互的方法,涉及针对WebBroswer控件及WebKit控件的相关使用技巧,需要的朋友可以参考下本文实例讲述了C#在WinForm中使用WebKit传递js对象实现与网页交互的方法。分享给... 查看详情

vs2008如何将c#写的winform程序打包成安装包?

我现在用C#写了Winform程序,想使用VS2008里面的安装程序项目打包的Winform程序并生成安装包。但是在打包过程中,需要将.NETFramework3.5和WindowsInstaller3.0打包到我的项目中,使用VS2008直接生成的安装包在安装过程中提示需要下载.NETFr... 查看详情

C#如何在treeview控件winform的所有父子节点中搜索文本

】C#如何在treeview控件winform的所有父子节点中搜索文本【英文标题】:C#Howtosearchatextinallparent&childnodesoftreeviewcontrolwinform【发布时间】:2019-11-0602:53:48【问题描述】:我正在递归搜索所有treeview的父节点和子节点中的文本,但没... 查看详情

如何在c#的winform中制作饼状图和柱状图

参考技术A你下载安装一个telerikforwinforms的插件上边有线程的插件可以直接用 查看详情

C# SkiaSharp OpenTK Winform - 如何从后台线程中绘制?

】C#SkiaSharpOpenTKWinform-如何从后台线程中绘制?【英文标题】:C#SkiaSharpOpenTKWinform-Howtodrawfromabackgroundthread?【发布时间】:2021-02-2013:04:35【问题描述】:我正在尝试将GDI+替换为SkiaSharp,以获得数据可视化框架,该框架使用实时不... 查看详情

如何在 C# winform 中每分钟自动调用一个方法

】如何在C#winform中每分钟自动调用一个方法【英文标题】:howtocallamethodeveryminautomacticinC#winform【发布时间】:2017-09-2514:43:36【问题描述】:在C#winform中每5秒自动运行一个函数当一个程序执行时我调用一个方法来加载我怎样才能... 查看详情