目的:获取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个串口,效率太低。

获取Windows系统中的所有可用和在用串口的更多相关文章

  1. Pyqt 获取windows系统中已安装软件列表

    开始之前的基础知识 1. 获取软件列表 在Python的标准库中,_winreg可以操作Windows的注册表.获取已经安装的软件列表一般是读去windows的注册表: SOFTWARE\Micros ...

  2. 这段百度问答,对我相关有对啊!!!----如何获取Windows系统登陆用户名

    如何获取Windows系统登陆用户名 http://zhidao.baidu.com/link?url=Hva9PkVwYZv8KSEWftSqTWe8fqM1dhoq59BurnfADmcOvFjF ...

  3. Windows系统中CreateFileMapping实现的共享内存及用法

    在32位的Windows系统中,每一个进程都有权访问他自己的4GB(232=4294967296)平面地址空间,没有段,没有选择符,没有near和far指针,没有near和far函数调用,也没有内存模 ...

  4. UEFI+GPT模式下的Windows系统中分区结构和默认分区大小及硬盘整数分区研究

    内容摘要:本文主要讨论和分析在UEFI+GPT模式下的Windows系统(主要是最新的Win10X64)中默认的分区结构和默认的分区大小,硬盘整数分区.4K对齐.起始扇区.恢复分区.ESP分区.MSR ...

  5. 通过PowerShell获取Windows系统密码Hash

    当你拿到了系统控制权之后如何才能更长的时间内控制已经拿到这台机器呢?作为白帽子,已经在对手防线上撕开一个口子,如果你需要进一步扩大战果,你首先需要做的就是潜伏下来,收集更多的信息便于你判断,便于有更大 ...

  6. 快速获取Windows系统上的国家和地区信息

    Windows系统上包含了200多个国家和地区的数据,有时候编程需要这些资料.以下代码可以帮助你快速获取这些信息.将Console语句注释掉,可以更快的完成分析. static void Main(s ...

  7. Python使用WMI模块获取Windows系统的硬件信息,并使用pyinstaller库编译打包成exe的可执行文件

    由于公司现阶段大多数应用软件都是基于Windows系统开发和部署,很多软件安装部署都是在windows server 2012.windows server 2008之类的服务器上,部门同事每次测试一 ...

  8. [源码]一键获取windows系统登陆密码vc6版源码

    [源码]一键获取windows系统登陆密码vc6版源码支持:XP/2000/2003/WIN7/2008等 此版本编译出来的程序体积较小几十KB... 而vs版则1点几M,体积整整大了2-30倍对某些 ...

  9. C/C++获取Windows系统CPU和内存及硬盘使用情况

    //1.获取Windows系统内存使用率 //windows 内存 使用率 DWORD getWin_MemUsage(){ MEMORYSTATUS ms; ::GlobalMemoryStatus ...

随机推荐

  1. webrtc视频数据解码处理流程

  2. Redis的那些最常见面试问题

    随笔:经过长达一周的奔波和面试,电话面试,回首今天终于成功的入职了,总共面试了大概10家公司,包括阿里,京东,IBM等等,京东技术过了,学历因为非统招就被pass了,阿里面了2次电话面试就没下文了,估 ...

  3. 前后端分离ueditor富文本编辑器的使用-Java版本

    最近在写一个自己的后台管理系统(主要是写着玩的,用来熟悉后端java的知识,目前只是会简单的写点接口),想在项目中编写一个发布新闻文章的功能,想到了使用百度的ueditor富文本编辑器,网上找了很多j ...

  4. Base64转换二进制文件对象 Blob/Base64转换 File 对象

    function convertBase64UrlToBlob(urlData) { var arr = dataurl.split(','),//去掉url的头,并转换为byte type = ar ...

  5. UILabletext去掉乱码 控制颜色 行高 自定义大小 。显示不同的字体颜色、字体大小、行间距、首行缩进、下划线等属性(NSMutableAttributedString)

    text去掉乱码 设置不同颜色 行高 自定义大小 #import <Foundation/Foundation.h> @interface TextsForRow : NSObject @ ...

  6. Spring MVC框架下的第一个Hello World程序

    本程序是一个maven程序,使用maven方便管理jar包和程序,简化了操作步骤.本程序的目的是通过一个简单的程序,了解Spring MVC框架的基本工作流程,由简入繁的学习Spring MVC框架, ...

  7. InnoDB 逻辑存储结构

    本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/80 如果创建表时没有显示的定义主键,mysql会按如下方式创建主 ...

  8. Python 项目实践三(Web应用程序)第二篇

    接着上节的继续学习,使用Django创建网页的过程通常分三个阶段:定义URL.编写视图和编写模板.首先,你必须定义URL模式,每个URL都被映射到特定的视图--视图函数获取并处理网页所需的数据.视图函 ...

  9. [编织消息框架][netty源码分析]1分析切入点

    在分析源码之前有几个疑问 1.BOSS线程如何转交给handle(业务)线程2.职业链在那个阶段执行3.socket accept 后转给上层对象是谁4.netty控流算法 另外要了解netty的对象 ...

  10. Webpack 2 视频教程 014 - 深入理解 Webpack 2 中的 loader

    原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...