目的:获取Windows系统中的所有可用和在用串口

方法:注册表查询法

优点:简单、实用、快速、无遗漏,无多余结果。

说明:另外还有8种方法可以枚举串口,但都不如此法。

代码和详细注释如下:

//---------------------------------------------------------------------------
// 枚举串口
void __fastcall TForm1::BtnEnumClick(TObject *Sender)
{
// 清除信息提示区
Memo1->Clear(); // 清空串口列表, sg 是 TStringGrid 对象
sg->Clear();
sg->Cells[0][0] = L"串口物理名称";
sg->Cells[1][0] = L"串口逻辑名称"; // 就是 COM1, COM2 之类的 // 列标题居中对齐
sg->Alignments[0][0] = taCenter;
sg->Alignments[1][0] = taCenter; // 创建注册表对象
std::auto_ptr<TRegistry> Registry(new TRegistry(KEY_READ));

try
{
// 注册表根路径
Registry->RootKey = HKEY_LOCAL_MACHINE; // 打开串口设备所在的注册表路径
bool bResult = Registry->OpenKey("\\HARDWARE\\DEVICEMAP\\SERIALCOMM", false); // 若打开注册表失败,提示信息,直接返回
if (!bResult) {
ShowHint("注册表路径不存在.");
return;
} // 数据项(名称)列表,就是串口物理名称列表
std::auto_ptr<TStringList> ItemNameList(new TStringList()); // 获取数据项(名称)列表,就是串口物理名称列表
Registry->GetValueNames(ItemNameList.get()); // 单个数据项的名称和值 (字符串形式),值的字符串形式就是串口逻辑名称,就是COM1, COM2 之类的
UnicodeString sItemName, sItemValue; // 逐个获取数据项值 (字符串形式)
for (int i = 0; i < ItemNameList->Count; i++)
{
// 当前数据项名称,也就是串口物理名称
sItemName = ItemNameList->Strings[i]; // 读取对应的数据项值 (字符串形式),也就是串口逻辑名称
sItemValue = Registry->ReadString(sItemName); // 显示串口物理名称和串口逻辑名称
//ShowHint(sItemName + "\t" + sItemValue);
// sg 是 TStringGrid 对象
sg->Cells[0][i + 1] = sItemName;
sg->Cells[1][i + 1] = sItemValue;
sg->AutoSizeColumns(true, 0);
} // 关闭会产生写入操作
//Registry->CloseKey();
}
// 在读取注册表时发生异常
catch(...) {
ShowHint("在读取注册表时发生异常.");
}
}
//---------------------------------------------------------------------------

以下是程序运行结果:

说明1:若只想获得可用(空闲)串口,还得逐个打开上述串口,成功打开的是可用(空闲)串口,否则为在用(被其它程序占用的)串口。

说明2:若要支持热插拔串口,还需响应 WM_DEVICECHANGE 消息。

枚举串口的各种方法对比

枚举串口方法

说明

EnumPorts

能够获得历史上曾经在系统中存在过的所有串口,不实用

WMI

无法获取纯粹用软件虚拟出来的串口,例如VSPD串口

注册表

简便、实用、快速,无遗漏,无多余

SetupAPI

GUID_DEVINTERFACE_COMPORT

结果同注册表法,但结果信息太详细,能够分辨出串口类型是纯软件虚拟的,还是蓝牙虚拟的,还是USB虚拟的,等等。

SetupAPI

Ports Device   information set

结果同注册表法,但结果信息太详细,能够分辨出串口类型是纯软件虚拟的,还是蓝牙虚拟的,还是USB虚拟的,等等。

GetDefaultCommConfig

结果有遗漏

QueryDosDevice

结果同注册表法,

文件读写法

结果同注册表法,但要尝遍255个串口,效率太低。

最新文章

  1. Python 字符串操作及string模块使用
  2. cain使用教程
  3. 基于sentinel 的redis集群环境搭建
  4. PHP多次调用Mysql存储过程报错解决办法
  5. 关于ARP攻击的原理以及在Kali Linux环境下的实现
  6. 统一软件开发过程(rup)理解
  7. IIS7下,flush无效,解决方案
  8. STM32F4_RCC系统时钟配置及描述
  9. [Objective-c 基础 - 1.1] OC类
  10. SCTP 关联的建立和终止
  11. PHPCMS 使用图示和PHPCMS二次开发教程(转)
  12. stl的集合set——安迪的第一个字典(摘)
  13. MySql每月增加一个分区以及查询所有分区
  14. 【第二篇】ASP.NET MVC快速入门之数据注解(MVC5+EF6)
  15. zabbix添加nginx监控
  16. eclipse中配置MAVEN并使用阿里云代理
  17. diary of laravel
  18. 组委会正在为美团点评CodeM大赛的决赛设计新赛制
  19. using 和try/catch区别和注意点
  20. 数据结构学习之stack

热门文章

  1. poj 2570 Fiber Network(floyd)
  2. 柯塔娜(Cortana):从科幻虚构到真实人生
  3. C#基础知识 结构与类的区别
  4. 页面的新开页,window.open的hacker
  5. 【转】Spring Bean单例与线程安全
  6. 两款主流项目管理软件PK,哪个更好用?
  7. 迭代var()内置函数的时候出现RuntimeError: dictionary changed size during iteration的解决办法
  8. iOS白名单设置
  9. 【java】多线程同步生产者消费者问题
  10. grep 、find 、tree 新发现