串口编程之端口
程序员文章站
2022-04-08 15:48:40
软件程序与硬件通过串口交换数据,首先要知道COM口,但是COM口是由计算机动态随机分配的。也就是说COM口的编号是变化的。因此我们在编程时不能将COM的编号写死。针对此问题我们想到的可能是将所有COM口读出来绑定到下拉框,软件启动后从下拉框选择需要的端口。或者写到配置文件,软件启动前在配置文件配置。 ......
软件程序与硬件通过串口交换数据,首先要知道com口,但是com口是由计算机动态随机分配的。也就是说com口的编号是变化的。因此我们在编程时不能将com的编号写死。针对此问题我们想到的可能是将所有com口读出来绑定到下拉框,软件启动后从下拉框选择需要的端口。或者写到配置文件,软件启动前在配置文件配置。不用说这两种方法都不是很理想。后来通过查询资料原来com口的变化会在注册表中记录。如图。
这样我们就有一个想法,能不能通过监控注册表来监测com口。于是有了下面代码。
1 using microsoft.win32; 2 using system; 3 using system.threading; 4 using system.threading.tasks; 5 6 namespace autotester.utilities 7 { 8 public class comlistenservice 9 { 10 /// <summary> 11 /// com监听服务类 12 /// </summary> 13 /// <param name="serialport">需要监听的端口</param> 14 //public comlistenservice(string serialport) 15 //{ 16 // _serialport = serialport; 17 //} 18 19 /// <summary> 20 /// 监听连接状态事件 21 /// </summary> 22 public event action<string, bool> connectionstatuschanged; 23 24 /// <summary> 25 /// 连接状态 26 /// </summary> 27 private bool _connectionstatus; 28 29 /// <summary> 30 /// 连接状态 31 /// </summary> 32 private bool connectionstatus 33 { 34 get { return _connectionstatus; } 35 set 36 { 37 if (_connectionstatus != value) 38 { 39 _connectionstatus = value; 40 connectionstatuschanged(_serialport, value); 41 } 42 } 43 } 44 45 46 /// <summary> 47 /// 开始监听 48 /// </summary> 49 public void startlisten() 50 { 51 _tokensource = new cancellationtokensource(); 52 53 task.factory.startnew(() => 54 { 55 listenning(); 56 }); 57 } 58 59 /// <summary> 60 /// 停止监听 61 /// </summary> 62 public void stoplisten() 63 { 64 _tokensource.cancel(); 65 } 66 67 /// <summary> 68 /// 监听端口 69 /// </summary> 70 public void listenning() 71 { 72 while (true) 73 { 74 thread.sleep(listenfrequency); 75 76 if (_tokensource.iscancellationrequested) 77 { 78 break; 79 } 80 81 lock (_locker) 82 { 83 bool isexist = false; 84 registrykey keycom = registry.localmachine.opensubkey(@"hardware\devicemap\serialcomm"); 85 if (keycom != null) 86 { 87 string[] ssubkeys = keycom.getvaluenames(); 88 89 foreach (string sname in ssubkeys) 90 { 91 string svalue = string.empty; 92 93 //if (svalue == _serialport) 94 //{ 95 // isexist = true; 96 // break; 97 //} 98 99 if (sname.contains("prolificserial") || sname.toupper().contains("vcp")) 100 { 101 _serialport = (string)keycom.getvalue(sname); 102 isexist = true; 103 break; 104 } 105 } 106 } 107 108 connectionstatus = isexist; 109 } 110 } 111 } 112 113 114 private string _serialport; 115 private cancellationtokensource _tokensource; 116 private const int listenfrequency = 1000; //监听频率(毫秒) 117 private static readonly object _locker = new object(); 118 } 119 }
(注:prolificserial和vcp和你的硬件设备有关,插上你的硬件后观察注册表变化)
调用非常简单,直接上代码。
1 comlistenservice cls = new comlistenservice(); 2 cls.connectionstatuschanged += cls_connectionstatuschanged; 3 cls.startlisten();
1 /// <summary> 2 /// 3 /// </summary> 4 /// <param name="comport"></param> 5 /// <param name="status"></param> 6 private static void cls_connectionstatuschanged(string comport, bool status) 7 { 8 if (status) 9 { 10 //comport已插入 11 } 12 else 13 { 14 //comport已拔出 15 } 16 }
测试后,完美一切正常。
上一篇: php启用zlib压缩文件的配置方法
下一篇: DSAPI 生成桌面图标(带数字)