☰
WinForms Expert Agent:老框架下BLE通信与控件知识库的工程实践
2026/10/20 5:36:54 网站建设 项目流程

1. WinForms Expert Agent 是什么,解决什么问题

先交代一下背景。我这两年大部分时间都在跟 WinForms 老项目打交道,不是那种新项目从零建模选型,而是从别人手里接过来的、运行了七八年的业务系统。系统里充斥着 DataGridView、TabControl、Timer、后台线程刷新 UI 这类经典场景。每次接到新需求,流程几乎固定:先翻旧代码,再拖控件,再查属性,再处理跨线程,最后看着 3000 行的 Form.cs 陷入沉思。

后来我开始把一个想法落地,也就是这个 WinForms Expert Agent 项目。它不是微软官方的产品,也不是某个大厂的开源框架,而是我做的一个“开发辅助智能体”,把 WinForms 开发中的控件经验、事件规则、通信能力(尤其是 BLE 蓝牙通信)沉淀成一套可复用的 Agent 系统。简单说,它就是一个懂 WinForms、能帮你直接生成 UI 代码、还能处理 .NET Framework 4.7.2 下 BLE 通信问题的专家代理。

这个项目适合谁参考?首先是还在维护 WinForms 老项目的开发朋友,其次是准备在传统 .NET Framework 框架下接入蓝牙硬件设备的团队,最后是对 AI Agent 辅助编程感兴趣、但不想一上来就上大模型全家桶的人。WinForms 虽然在很多技术社区里已经不太“时尚”,但存量项目数量巨大,工厂管理系统、医疗仪器上位机、仓储调度端,到处是它的影子。把 Expert Agent 用在 WinForms 上,不是炫技,而是踏踏实实降低重复劳动。

它解决的问题可以归纳成三个:

  • 把松散的控件、属性、事件、方法知识整理成结构化知识库,让开发时不用反复搜文档。
  • 把 BLE 通信这种容易踩坑的能力封装成可复用模块,让老框架也能顺畅对接蓝牙设备。
  • 让开发者的自然语言描述能直接映射到 WinForms 代码,缩短“需求到界面”的距离。

我后面所有内容,都会围绕这三个点展开。

2. 核心思路:Expert Agent 的知识底座与控件知识库设计

做 Agent 之前,我最担心的是把整个系统设计得太重。如果一开始就引入大语言模型、向量数据库、复杂代理框架,那这个项目大概率活不过两周,因为维护成本太高了。所以我把整个架构收敛成了三层:知识层、能力层、编排层。知识层负责回答“WinForms 这些东西到底怎么用”,能力层负责回答“BLE 这类具体功能怎么实现”,编排层负责把用户需求翻译成知识层和能力层能执行的指令。

2.1 为什么先做控件知识库

WinForms 开发最大的特点,就是“控件驱动”。业务界面不管多复杂,归根结底就是若干控件的组合。我见过太多同事写界面时频繁查属性,DataGridView 的 AutoSizeColumnsMode、TextBox 的 MaxLength、ComboBox 的 DropDownStyle,每次都靠记忆或者搜索引擎。把这些东西沉淀成知识库之后,Agent 才能在工作时直接引用,而不是靠猜。

我设计的知识条目结构大致是:

{ "controlType": "DataGridView", "displayName": "数据表格", "commonProperties": [ { "name": "DataSource", "description": "绑定数据源,建议用 BindingList 或 DataTable" }, { "name": "AutoGenerateColumns", "description": "是否自动生成列,默认 true" }, { "name": "ReadOnly", "description": "只读模式,配合 SelectionMode 使用" } ], "commonEvents": [ { "name": "CellClick", "description": "点击单元格后触发,适合做行选择" }, { "name": "CellDoubleClick", "description": "双击单元格,常用于打开编辑窗口" } ], "commonMethods": [ { "name": "ClearSelection", "description": "清除所有选中行" }, { "name": "EndEdit", "description": "结束编辑状态,提交当前修改" } ], "tips": ["刷新数据源后需要重新绑定,否则界面不更新"] }

这个结构看起来很土,但非常实用。它让我能直接把这个知识库喂给 Agent 使用。不需要向量化,不需要语义搜索,用关键词匹配加上几组正则,就能覆盖大部分日常需求。因为 WinForms 控件知识是比较固定的,属性名、事件名不会变来变去,规则先行、模型兜底才是务实的做法。

2.2 高频控件梳理:Agent 先要学会这些

知识库必须有优先级。我根据实际项目使用频率,把控件分成了几个梯队:

第一梯队是必知必会:Button、TextBox、Label、Panel、ComboBox、CheckBox、DateTimePicker。这些控件是大多数界面的基础构件。它们的属性值得重点记忆,比如 TextBox 的 Multiline、ScrollBars、AcceptsReturn,ComboBox 的 DropDownStyle 在用户输入场景下必须设置成 DropDown 而不是 DropDownList。

第二梯队是数据核心:DataGridView、ListBox、ListView、TreeView。这里 DataGridView 是最重的。光是 DataGridView 就值得单独建一个知识子库,因为它有五十多个属性、二十多个事件。实际经验告诉我,DataGridView 最重要的三个属性是 DataSource、AutoGenerateColumns、ReadOnly,最重要的三个事件是 CellClick、CellDoubleClick、DataBindingComplete。只要把这三个属性和三个事件讲清楚,80% 的开发场景都能覆盖。

第三梯队是后台与定时任务:Timer、BackgroundWorker、NotifyIcon。WinForms 项目里 Timer 是隔三差五就要用的,比如定时轮询设备状态、定时刷新界面数据。BackgroundWorker 在 .NET Framework 4.7.2 下依然是处理后台任务最顺手的方式之一,虽然现在都讲 async/await,但老项目里 BackgroundWorker 的使用频率一点都不低。

我让 Agent 只优先学习这三个梯队,而不是把所有控件都塞进去。因为知识库越大,匹配准确率越差。宁可少而精,也不要多而杂。这个原则在整个 Expert Agent 项目里一直没变。

2.3 把属性、事件、方法的“语法”教给 Agent

控件知识库只是“词汇表”,真正的功力在于怎么把这些词汇组合成有效的代码。所以我在 Agent 里加了一套“意图映射规则”。

核心逻辑是:从用户的自然语言描述中提取动作词,然后映射到控件事件和属性操作。

  • 用户说“点击按钮”,映射到 Button.Click 事件。
  • 用户说“窗口加载时”,映射到 Form.Load 事件。
  • 用户说“双击行”,映射到 DataGridView.CellDoubleClick。
  • 用户说“隐藏这个按钮”,映射到 button.Visible = false。
  • 用户说“禁用输入框”,映射到 textBox.Enabled = false。
  • 用户说“下拉框里加几个选项”,映射到 comboBox.Items.AddRange(...)。

这套映射一开始我用字典硬编码,后来发现不够,因为用户表达方式千奇百怪。比如“让界面别乱动”可能是指 AutoScroll 或者 Dock 属性。于是我在字典基础上加了一组近义词扩展,比如“ 禁点、不可点、灰掉 ”都映射到 Enabled=false,“醒目、高亮、标红”映射到 BackColor 或 ForeColor。

对于有一定经验的人来说,可能会问:为什么不用大模型来做意图识别?我的回答是:可以用,但需要兜底。大模型理解自然语言确实更强,但它生成代码时经常犯低级错误,比如属性名写错、事件绑定漏掉、跨线程访问不包 Invoke。所以我的方案是:大模型负责“理解”,规则层负责“校验和补全”。这是 Expert Agent 和普通 AI 编程助手最大的区别。

3. BLE 通信能力:.NET Framework 4.7.2 下的第三方库选型与实践

如果说控件知识库是 Agent 的“内功”,那 BLE 通信就是 Agent 的“外功”。我接到不少需求,是 WinForms 老系统要对接蓝牙设备,比如体温枪、心率带、蓝牙打印机、BLE 信标。老框架想直接调系统蓝牙 API,并没有默认支持,必须先选好第三方库。

3.1 常见第三方库横向对比

我把 .NET Framework 4.7.2 下能用的方案都过了一遍,主要筛出三个:

方案优点缺点适合场景
32feet.NET(InTheHand.Net.Bluetooth)老牌、文档多、经典蓝牙支持好,引入 NuGet 包即可BLE 支持偏弱,GATT 操作接口写起来反直觉,部分功能依赖本机蓝牙栈只做串口蓝牙、经典蓝牙耳机、老式蓝牙设备
Microsoft.Windows.SDK.Contracts + C#/WinRT直接调用 Windows 10+ 的 BLE API,功能完整,支持 GATT、广播监听、电量读取需要额外配置互操作,代码偏现代化,在老框架下要注意目标平台主攻 BLE 设备的项目,比如 BLE 体温计、信标扫描
自己封装 P/Invoke 调 Win32/BTH.dll无第三方依赖、完全可控开发量大,调试难度高,稳定性可疑极个别特殊场景,不推荐

我在项目里实测下来,结论非常直接:如果明确要跟 BLE 设备打交道,首选 Microsoft.Windows.SDK.Contracts。老牌 32feet.NET 在经典蓝牙场景很稳定,但处理 BLE 的广播扫描和 GATT 服务时会明显吃力。我实际遇到过一个情况,用 32feet.NET 扫描 BLE 体温计,扫到的设备地址是对的,但怎么都读不出温度值,后来换到 Windows.Devices.Bluetooth 才通了。

3.2 如何在 4.7.2 项目里配置 Windows.Devices.Bluetooth

这里要先说清楚一个前提。.NET Framework 4.7.2 本身没有内置 Windows.Devices.Bluetooth,这个 API 是 Windows Runtime(WinRT)的一部分。要让老框架项目调用它,需要安装 Microsoft.Windows.SDK.Contracts 包,它会在项目里自动生成 WinRT interop 桥接。

具体步骤:

  1. 在 NuGet 中安装Microsoft.Windows.SDK.Contracts,选择与目标 Windows 版本匹配的版本(建议 10.0.19041.0 以上)。
  2. 确认项目目标框架设置为net472,并且Windows.Forms项目本身能正常编译。
  3. 在代码文件顶部加上using Windows.Devices.Bluetooth;、using Windows.Devices.Bluetooth.Advertisement;、using Windows.Devices.Bluetooth.GenericAttributeProfile;。

这个配置我重做过三遍,踩过的坑主要是版本不一致。如果你用的 SDK Contracts 版本比系统实际版本低,运行时会出现方法找不到的错误。另外,这个包只支持 Windows 10 1803 以上的系统,如果客户还在 Windows 7,这条路就走不通,只能退回经典蓝牙或者换设备侧方案。

3.3 用 BluetoothLEAdvertisementWatcher 实现 BLE 扫描

Agent 里最常用的能力就是扫描附近 BLE 设备。核心类是BluetoothLEAdvertisementWatcher,它专门监听 BLE 广播包。

以下这段代码,是 Agent 生成的典型扫描逻辑:

using System; using System.Collections.Generic; using System.Threading; using System.Windows.Forms; using Windows.Devices.Bluetooth.Advertisement; public class BleScanner { private BluetoothLEAdvertisementWatcher _watcher; public event Action<string, ulong, short> DeviceFound; public void StartScan(int scanDurationSeconds = 10) { _watcher = new BluetoothLEAdvertisementWatcher(); _watcher.ScanningMode = BluetoothLEScanningMode.Active; _watcher.Received += OnAdvertisementReceived; _watcher.Start(); Thread.Sleep(TimeSpan.FromSeconds(scanDurationSeconds)); if (_watcher.Status == BluetoothLEAdvertisementWatcherStatus.Started) { _watcher.Stop(); } } private void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args) { string name = args.Advertisement.LocalName; ulong address = args.BluetoothAddress; short rssi = args.RawSignalStrengthInDBm; if (!string.IsNullOrEmpty(name) || rssi > -100) { DeviceFound?.Invoke(name, address, rssi); } } }

这里有几个关键点:

  • ScanningMode.Active会主动发送扫描请求,让设备回应更多信息,很多外设只在 Active 模式下才会返回名称。
  • BluetoothAddress是一个 UInt64,直接输出会是一个很长的数字,需要按 MAC 格式转换显示。
  • RawSignalStrengthInDBm就是 RSSI,数值越大代表信号越强,但它是短整型,负数正常。
  • 这个事件触发在后台线程,如果你直接把条目加到 ListView 或 DataGridView,一定会报“线程间操作无效”的异常,必须用Invoke或BeginInvoke回主线程。

我把这些点直接固化在 Agent 的规则里。Agent 生成 BLE 扫描代码时,自动带上一个SafeInvoke工具类,保证后台线程操作 UI 不报错。这是一个非常实用的细节,很多人第一次写 BLE 扫描程序,代码本身没问题,全是挂在跨线程上。

3.4 连接 BLE 设备并读写 GATT 特征值

扫描到设备之后,要真正和设备交互,需要走 GATT(通用属性配置文件)协议。GATT 的模型是“服务(Service)- 特征(Characteristic)- 值(Value)”,比如一个心率设备,它有“心率服务”,服务下面有“心率测量特征”,特征值就是那一串实时心率数据。

连接并读取特征值的核心代码如下:

using Windows.Devices.Bluetooth; using Windows.Devices.Bluetooth.GenericAttributeProfile; using Windows.Storage.Streams; public async System.Threading.Tasks.Task<string> ReadHeartRateAsync(ulong bluetoothAddress) { BluetoothLEDevice device = await BluetoothLEDevice.FromBluetoothAddressAsync(bluetoothAddress); if (device == null) return null; GattDeviceServicesResult servicesResult = await device.GetGattServicesAsync(); if (servicesResult.Status != GattCommunicationStatus.Success) return null; foreach (GattDeviceService service in servicesResult.Services) { GattCharacteristicsResult characteristicsResult = await service.GetCharacteristicsAsync(); if (characteristicsResult.Status != GattCommunicationStatus.Success) continue; foreach (GattCharacteristic characteristic in characteristicsResult.Characteristics) { // 心率测量特征的 UUID 是 0x2A37,也可以直接用字符串比较 if (string.Equals(characteristic.Uuid.ToString(), "00002a37-0000-1000-8000-00805f9b34fb", StringComparison.OrdinalIgnoreCase)) { GattReadResult readResult = await characteristic.ReadValueAsync(); if (readResult.Status == GattCommunicationStatus.Success) { DataReader reader = DataReader.FromBuffer(readResult.Value); byte[] bytes = new byte[reader.UnconsumedBufferLength]; reader.ReadBytes(bytes); return BitConverter.ToString(bytes); } } } } return null; }

这段代码浓缩了几个 BLE 开发的常见坑:

  • 不是所有设备都支持直接ReadValueAsync,有些心率设备是主动通知,需要注册ValueChanged事件、设置CCCD描述符。
  • UUID 有大写小写和短格式长格式之分,一定要统一转成小写再比较,否则匹配不上。
  • GattCommunicationStatus.Success不等于数据正确,还要自己解析字节。
  • 设备枚举和连接过程在 WinForms 老项目里,不能用Wait()阻塞主线程,否则界面卡死。正确做法是async void事件处理器里加await,或者统一封装成async Task。

这些经验,我全部写进了 Agent 的 BLE 能力模块。Agent 生成代码时,会自动识别“读取心率”“订阅通知”“写特征值”等意图,然后匹配不同的代码骨架。

4. 实操全流程:让 Agent 从需求生成一个 BLE 扫描界面

理论讲得再多,不如完整跑一遍流程。下面我用一个非常具体的需求演示 WinForms Expert Agent 怎么工作。

需求描述是:在 WinForms 里做一个 BLE 扫描界面,点击“开始扫描”按钮后,列表展示附近 BLE 设备的名称、MAC 地址、RSSI,双击某个设备可以连接,并在界面上显示该设备的 RSSI 和连接状态。

这个需求看起来简单,但手工写代码至少需要处理 UI 布局、事件绑定、后台扫描、蓝牙 API 调用四个部分。Agent 的流程是三步走。

4.1 需求解析与意图拆分

Agent 先对用户输入做拆解,识别出四个关键意图:

  • “点击开始扫描” -> Button 的 Click 事件,调用 BLE 扫描器。
  • “列表展示附近设备” -> 使用 ListView 或 DataGridView,列分别为名称、MAC、RSSI。
  • “双击某个设备可以连接” -> ListView 的 MouseDoubleClick 或者 DataGridView 的 CellDoubleClick。
  • “显示连接状态” -> 添加 Label 控件,更新文本。

Agent 同时识别出这是一个 BLE 场景,于是自动引入 Windows.Devices.Bluetooth 相关命名空间,并带上跨线程安全调用机制。

4.2 Agent 生成的界面骨架代码

下面是 Agent 生成的核心代码段,去掉了非必要细节:

public partial class BleScanForm : Form { private ListView listViewDevices; private Button btnStart; private Label lblStatus; private BleScanner _scanner = new BleScanner(); public BleScanForm() { InitializeComponent(); SetupUi(); } private void SetupUi() { this.Text = "BLE 设备扫描"; this.Size = new Size(700, 450); listViewDevices = new ListView(); listViewDevices.View = View.Details; listViewDevices.FullRowSelect = true; listViewDevices.GridLines = true; listViewDevices.Columns.Add("名称", 200); listViewDevices.Columns.Add("MAC", 150); listViewDevices.Columns.Add("RSSI", 80); listViewDevices.Dock = DockStyle.Top; listViewDevices.Height = 300; listViewDevices.MouseDoubleClick += ListViewDevices_MouseDoubleClick; btnStart = new Button(); btnStart.Text = "开始扫描"; btnStart.Location = new Point(12, 320); btnStart.Click += BtnStart_Click; lblStatus = new Label(); lblStatus.Text = "等待扫描"; lblStatus.Location = new Point(120, 325); lblStatus.AutoSize = true; this.Controls.Add(listViewDevices); this.Controls.Add(btnStart); this.Controls.Add(lblStatus); _scanner.DeviceFound += OnDeviceFound; } private void BtnStart_Click(object sender, EventArgs e) { listViewDevices.Items.Clear(); lblStatus.Text = "扫描中..."; _scanner.StartScan(8); lblStatus.Text = "扫描结束"; } private void OnDeviceFound(string name, ulong address, short rssi) { if (listViewDevices.IsDisposed || listViewDevices.Disposing) return; if (listViewDevices.InvokeRequired) { listViewDevices.BeginInvoke(new Action(() => OnDeviceFound(name, address, rssi))); return; } var item = new ListViewItem(string.IsNullOrEmpty(name) ? "未知设备" : name); item.SubItems.Add(address.ToString("X12")); item.SubItems.Add(rssi.ToString()); listViewDevices.Items.Add(item); } private async void ListViewDevices_MouseDoubleClick(object sender, MouseEventArgs e) { if (listViewDevices.SelectedItems.Count == 0) return; string macHex = listViewDevices.SelectedItems[0].SubItems[1].Text; ulong address = Convert.ToUInt64(macHex, 16); lblStatus.Text = "连接中..."; string data = await ReadHeartRateAsync(address); lblStatus.Text = data != null ? "连接成功,数据: " + data : "连接失败"; } }

你注意看,OnDeviceFound方法里用了BeginInvoke+return的写法,这是应对后台线程和 UI 同时访问控件的标准姿势。BeginInvoke是异步调用主线程更新,不会阻塞扫描线程,所以即使设备很多,界面也不会卡顿。

4.3 编译运行与效果评估

我把 Agent 生成的代码直接丢进一个 .NET Framework 4.7.2 的 WinForms 项目里,一次通过编译,运行后能正常列出附近的 BLE 设备。双击设备后会去尝试连接,对于支持 Generic Access Profile 的设备,能顺利读取到特征值数据。

但这个流程里有一个隐藏问题:Agent 生成的ReadHeartRateAsync是简单示例,真实设备特征值千奇百怪。比如很多设备需要先订阅ValueChanged事件,而不是直接 Read。所以我开发时就给 Agent 加了一个“连接后处理策略”:默认生成可读代码,但保留一个高级选项,由开发者选择目标设备类型,是“可读设备”还是“通知设备”,Agent 再切换代码模板。这种细节,正是把 Agent 工程化之后带来的好处。

前几年我会觉得写这种界面太简单,不值得花时间做 Agent。但当我同时接三四个项目、每个项目都要加 BLE 模块时,“生成一次模板—微调—上线”的速度优势就明显了。实测下来,同一个扫描界面,手工写带跨线程处理和事件绑定的完整代码,大概需要四十分钟到一个小时;Agent 生成后微调,十分钟内搞定。

5. 常见问题与排查技巧实录

这部分是我在最开始下决心开发 Expert Agent 时,反复遇到问题的记录。不整理成速查表,真到用的时候容易慌。

5.1 BLE 扫描不到设备的排查顺序

这是最容易让人崩溃的一个问题,写好了扫描代码,结果列表空白。我的排查顺序是:

  1. 确认设备真的在广播。很多设备在未进入配对模式时不广播或者广播频率很低,需要按设备说明书进入广播状态。
  2. 确认扫描模式。默认的ScanningMode.Passive只能拿到部分广播信息,改成Active能拿到更多响应。
  3. 确认代码运行的操作系统版本。Windows 10 以下不支持 BLE API。
  4. 确认电脑的蓝牙适配器支持 BLE。早期蓝牙 4.0 适配器不一定正常,最好用蓝牙 5.0 以上的。
  5. 检查 RSSI 过滤条件。我加了一句if (!string.IsNullOrEmpty(name) || rssi > -100),如果设备没有广播名且 RSSI 低于 -100,直接被过滤掉,看不到。

如果按这个顺序还扫不到,再用第三方的 BLE 调试工具(比如 Windows 自带的蓝牙设备列表或者手机 App)交叉验证,判断到底是代码问题还是设备问题。

5.2 Microsoft.Windows.SDK.Contracts 在 4.7.2 项目里的坑

这个包集成好之后,编译没问题,但运行时容易抛TypeLoadException或NotSupportedException。我遇到的典型场景是:方法能调用,但某些 API 返回 null。原因基本是系统版本太低。所以我的策略是:项目里统一做一次运行系统版本检测,不满足就给出明确提示,而不是让客户面对一个莫名其妙的异常。

using System; public static class SystemCheck { public static void EnsureBleSupport() { Version osVersion = Environment.OSVersion.Version; if (osVersion.Major < 10) { throw new NotSupportedException("BLE 扫描需要 Windows 10 或更高版本"); } } }

这个检查放在 Agent 生成的代码最前面,亲测能省下大量排查时间。

5.3 32feet.NET 和 BLE 的兼容边界

如果你还是坚持以 32feet.NET 为主,一定要清楚它的边界。它在经典蓝牙 RFCOMM 通道上非常强大,做蓝牙串口透传很稳。但 BLE 的广播监听能力较弱,写 GATT 时要自己处理很多事情,而且不同版本的 Windows 蓝牙栈行为不一致。我的一个蓝牙项目是给老设备做工具,用 32feet.NET 连接一个蓝牙 2.0 串口模块,非常稳定。但同时要扫描一个 BLE 信标,它就无能为力了,最后还是切换到 Microsoft.Windows.SDK.Contracts。

所以选型建议是:确定是经典蓝牙设备,选 32feet.NET;确定是 BLE 设备,选 Windows.Devices.Bluetooth。如果两种都要支持,那就两个库都引用,用代码区分场景。Agent 的知识库里也明确写了这条规则。

5.4 Agent 生成代码的典型低级错误

Agent 再聪明,也会在一开始生成一些看着合理但不合用的代码。我总结了三个高频问题,全部写进了自检规则:

第一个是事件绑定漏掉。它会生成btnStart.Click += BtnStart_Click;但BtnStart_Click方法名拼错,编译不报错,点按钮没反应。原因是 WinForms 的事件订阅是编译期强绑定的,但方法名如果拼对但逻辑为空,运行时不报错也没有效果。

第二个是控件布局互相重叠。WinForms 默认绝对定位,Agent 生成的控件坐标容易超出窗体边界,Dock 属性错误导致控件挤在一起。我的补丁是让 Agent 生成时统一用 Anchor 或 Dock,并在生成后自动检查控件边界。

第三个是跨线程访问。这个之前说过。Agent 生成的代码如果不默认带InvokeRequired判断,运行几秒就可能抛异常。我在 Agent 的每个 UI 更新方法生成规则里,强制加上BeginInvoke包装。

这些自检规则不一定百分之百解决所有问题,但确实让 Agent 生成的代码从“半成品”提升到“可直接改改就能用”的程度。

6. 把 Expert Agent 继续扩展的一点心得

做这个项目之前,我一直觉得所谓 Expert Agent 是一个很玄的东西,可能是要训练一个大模型,或者要搭一个完整的知识图谱。实际做完才发现,对 WinForms 这个确定性非常强的领域,一个“规则 + 代码模板 + 经验库”的组合就已经能发挥很大作用。

如果后续要继续扩展,我觉得最值得做的是把更多通信能力加进去,比如串口通信、Modbus 协议、Socket TCP/IP 通信。WinForms 老项目里这类需求非常多,而且它们的共性都是:后台线程、数据解析、UI 刷新。一旦 Agent 的通信能力库丰富起来,它就不再只是 BLE 专家,而是整个 WinForms 上位机的“百事通”。

另外一个小建议,如果是团队使用,最好把知识库和代码模板放在一个统一的仓库里维护,每次在真实项目里发现问题,就补一条规则进去。这个项目最大的价值不是我写了多少代码,而是它把一次性的经验,变成了可持续积累的资产。我现在维护的三个老项目,都开始用这套 Agent 生成菜单类界面、报表查询界面,效率提升非常明显。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询