`
guiven
  • 浏览: 28906 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

c++枚举串口4法

阅读更多

1 、查询注册表
查询注册表的方法是网上见到的比较常见的方法,该方法就是使用编程方法读取注册表内信息,相当于用户通过在运行框内输入 ”regedit” (或 regedit32 )直接打开注册表,查看“ HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM ”项来获取串口信息。以下是源代码:
CString  strSerialList[256];      // 临时定义 256 个字符串组,因为系统最多也就 256 个
HKEY hKey;
LPCTSTR data_Set="HARDWARE\\DEVICEMAP\\SERIALCOMM\\";
long ret0 = (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_Set, 0, KEY_READ, &hKey));
if(ret0 != ERROR_SUCCESS)
{
return -1;
}
int i = 0;
CHAR Name[25];
UCHAR szPortName[25];
LONG Status;
DWORD dwIndex = 0;
DWORD dwName;
DWORD dwSizeofPortName;
DWORD Type;
dwName = sizeof(Name);
dwSizeofPortName = sizeof(szPortName);
do
{
Status = RegEnumValue(hKey, dwIndex++, Name, &dwName, NULL, &Type,
      szPortName, &dwSizeofPortName);
if((Status == ERROR_SUCCESS)||(Status == ERROR_MORE_DATA))
{
strSerialList[i] = CString(szPortName);   // 串口字符串保存
i++;// 串口计数
   }
} while((Status == ERROR_SUCCESS)||(Status == ERROR_MORE_DATA));
RegCloseKey(hKey);

以上方法同样也可以实现对并口的查询,只要将 "HARDWARE \\ DEVICEMAP\\ SERIALCOMM\\" 用 "HARDWARE\\DEVICEMAP\\PARALLEL PORTS\\" 代替就行了。
比较:该方法时间最省,笔者在自己电脑上试过,在 1ms (少于 1ms 的我也不知道怎么编程计时)内即可完成;同时也可解决 usb 转串口设备的问题,比较实用,唯一缺点是,如果用户在装某些软硬件时在注册表中注册了虚拟串口之类的,用此法枚举得到的该类串口实际上是不能当串口用的。

2 、使用 EnumPort 方法
该方法调用 EnumPort () API 函数,该函数本身就是枚举电脑端口用的,它枚举的并非只有串口,所以必须对其所得串口进行分析选择,以下是源代码:
       int m_nSerialPortNum(0);// 串口计数
       CString         strSerialList[256];      // 临时定义 256 个字符串组
       LPBYTE pBite  = NULL;
       DWORD pcbNeeded = 0;  // bytes received or required
       DWORD pcReturned = 0;  // number of ports received
       m_nSerialPortNum = 0;
       // 获取端口信息,能得到端口信息的大小 pcbNeeded
       EnumPorts(NULL, 2, pBite, 0, &pcbNeeded, &pcReturned);
       pBite = new BYTE[pcbNeeded];
       // 枚举端口,能得到端口的具体信息 pBite 以及端口的的个数 pcReturned
       EnumPorts(NULL, 2, pBite, pcbNeeded, &pcbNeeded, &pcReturned);
       PORT_INFO_2 *pPort;
       pPort = (PORT_INFO_2*)pBite;
       for ( i = 0; i < pcReturned; i++)
       {
              CString str = pPort[i].pPortName;
              // 串口信息的具体确定
              if (str.Left(3) == "COM")
              {                  
                     strSerialList[m_nSerialPortNum] = str.Left(strlen(str) - 1);
                     //CString temp = str.Right(strlen(str) - 3);// 下面两行注释获取串口序号用
                     //m_nSerialPortNo[m_nSerialPortNum] = atoi(temp.Left(strlen(temp) - 1));
                     m_nSerialPortNum++;                   
              }
       }

以上方法除了串口,还可以枚举所有的并口和打印机等接口,而且能找到虚拟串口(这些串口有些未使用时,在注册表和硬件设备管理器中是不能取得的)。但是该方法稍微耗时些,笔者在自己电脑上试过,大概需要几十 ms ,主要问题是该方法有些 usb 串口并不能查到,所以该方法并不可靠。

3 、依次打开串口的方法
该方法就是中规中矩的依次打开串口,看打开是否成功来判断串口的有无,该方法源代码如下:
       int m_nSerialPortNum(0);// 串口数
       CString         strSerialList[256];      // 临时定义 30 个字符串组
       int nCom = 0;
       int count = 0;
       HANDLE hCom;
       do {
              nCom++;
              strCom.Format("COM%d", nCom);
              hCom = CreateFile(strCom, 0, 0, 0,
                     OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
              if(INVALID_HANDLE_VALUE == hCom )
                     break;
              strSerialList[m_nSerialPortNum] = strCom;
              m_nSerialPortNum++;            
              CloseHandle(hCom);
       } while(1);

以上方法枚举的都是当前可用的串口,如果有一个串口当前被占用则其后的串口也将无法枚举得到,当然以上方法也可以改成调用 for 循环让其枚举打开 256 个串口的方法以避免上述情况,不过该方法比前两种更耗时(一般查找一个串口就要 15ms 左右),不过可以枚举得到所有当前可打开的串口,当然不能枚举得到一些虚拟串口。

4 、使用 SetupAPI 函数集的方法
此种方法是我所见过最简单的方法,之所以简单是因为已经有人将复杂的代码封装起来了,我只需像傻子一样调用就可以完成工作了,具体的说明请看 http://www.codeguru.com/Cpp/W-P/system/hardwareinformation/article.php/c5721/ ,下面给出本人调用该方法的例子代码:
       int m_nSerialPortNum(0);// 串口计数
       CString         strSerialList[256];      // 临时定义 256 个字符串组
       CArray<SSerInfo,SSerInfo&> asi;
        EnumSerialPorts(asi,TRUE);// 参数为 TRUE 时枚举当前可以打开的串口,
// 否则枚举所有串口
       m_nSerialPortNum = asi.GetSize();
       for (int i=0; i<asi.GetSize(); i++)
       {
              CString str = asi[i].strFrien dlyName;
       }

补充说明一下,使用该方法只要在你的程序中,添加“ EnumSerial.cpp ”和“ EnumSerial.h ”两个文件,并且将 Setupapi.lib 包含进你的工程文件中就行了,该方法时间上来说可能和第三种方法差不多,但该方法获取的串口完完全全就是硬件设备管理器中的串口。
分享到:
评论

相关推荐

    C++ SerialEnum 串口枚举实例

    串行接口,简称串口,是设备之间通过串行方式进行通信的一种接口。在个人电脑上,常见的串口包括COM1、COM2等,它们遵循RS-232标准。串口通信涉及到的主要参数有波特率(如9600bps)、数据位(通常为8位)、停止位...

    VC枚举串口号(串口名)

    "VC枚举串口(串口名)"这个标题指的是利用VC++(Visual C++)来查找并列举系统中可用的串行端口名称。在描述中提到的"EnumSerial"是一个自定义类,它被用来实现串口的枚举功能,能够识别虚拟串口并且能够在串口号超过...

    枚举可用串口(VC++)

    枚举串口的过程主要涉及到Windows API函数的调用,尤其是`SetupDiGetClassDevs`和`SetupDiEnumDeviceInterfaces`这两个函数。`SetupDiGetClassDevs`用于获取设备安装类的信息,而`SetupDiEnumDeviceInterfaces`则...

    VC++语言编写,枚举当前系统中的所有RS232串口.zip

    3. 枚举RS232串口:RS232是早期广泛使用的串行通信接口标准,用于连接计算机和外设。在VC++中,通过调用Windows API函数如`SetupDiGetClassDevs`、`SetupDiEnumDeviceInfo`等,可以获取系统中的串行端口信息。这些...

    Linux下C++串口通信

    Linux下C++串口通信,支持ubuntu,树莓派等系统。

    枚举系统中全部串口

    以C#为例,我们可以利用.NET Framework提供的`System.IO.Ports`命名空间中的`SerialPort`类来枚举串口。以下是一个简单的示例代码: ```csharp using System.IO.Ports; public static void EnumerateSerialPorts()...

    枚举Windows串口的Demo

    学习和理解这个Demo,不仅可以帮助你掌握如何在Windows环境下枚举串口,还能让你深入理解MFC的类库使用,以及Windows底层设备通信的原理。这对于进行硬件交互和设备驱动程序开发的程序员来说是非常有价值的。通过...

    windows枚举串口

    在Windows操作系统中,枚举串口是一项常见的任务,特别是在开发涉及串行通信的软件时。本文将详细讲解如何使用C++、Visual Studio 2008(VS2008)、MFC(Microsoft Foundation Classes)以及COMBO BOX控件来实现这一...

    C/C++语言实现串口(USB)的数据收发

    在IT领域,尤其是在嵌入式系统或物联网应用中,C/C++语言经常被用来实现串口(Serial Port)或USB接口的数据收发功能。串口通信是一种基础的、通用的设备间通信方式,而USB(Universal Serial Bus)则提供了一种更...

    vs2005 枚举串口源代码

    枚举串口是指程序通过遍历系统中所有可用的串行端口(COM1、COM2、COM3...)来获取它们的信息,如端口号、硬件描述、当前的波特率等。在Windows环境下,这通常涉及到使用Windows API函数,特别是那些与设备管理相关...

    c++ 串口类 读 写 取得串口列表

    在C++编程中,串口通信是连接硬件设备和计算机之间的一种重要方式,常用于工业控制、嵌入式系统和物联网应用。本文将详细讲解如何使用C++进行串口操作,包括打开、关闭串口、读取和写入数据以及获取可用串口列表。 ...

    枚举 USB HUB 设备

    例如,`SetupDiGetClassDevs`函数可以获取指定设备类的所有设备实例,`SetupDiEnumDeviceInterfaces`可以枚举设备接口,`SetupDiOpenDeviceInterface`则用于打开设备接口,以便进一步操作。 此外,`USBView`工具是...

    USB.rar_C++枚举USB_USB 枚举_usb packet_usb 包

    在"USB.rar_C++枚举USB_USB 枚举_usb packet_usb 包"这个压缩包中,我们主要探讨的是USB协议的枚举过程、数据包分析以及USB标准描述符这三个关键领域。 首先,USB的**枚举过程**是设备连接到主机后的初始化阶段。在...

    usb.rar_C++枚举USB_USB copy data _usb

    C++枚举USB是指在C++编程中处理USB设备枚举的过程,这通常涉及到识别、列举和管理连接到系统的USB设备。 在USB的数据传输过程中,有若干关键步骤和概念需要理解: 1. **枚举过程**:当USB设备插入到主机后,会触发...

    串口枚举类

    一个简单易用的串口枚举类.可以枚举出系统内所有曾用过的串口号.可以选择只枚举物理串口,或者枚举已存在的串口,屏蔽未使用的虚拟串口.代码已经封装成类,可以与组合框控件或列表框控件关联,即可将系统中可用的串口...

    c++ 异步串口源码

    总之,C++中的异步串口通信涉及了多线程、回调函数、事件驱动编程等概念,通过封装API接口,可以有效地简化串口操作,提高代码的可读性和可维护性。理解并掌握这些知识点对于进行低级硬件通信或者嵌入式系统的开发至...

    串口设备枚举类 实现串口枚举 串口打开 添加到combobox 下拉列表中

    代码可能包括一个名为`SerialEnumerator`的类,其中包含了枚举串口、添加到ComboBox以及打开串口的方法。通过分析和理解这段代码,开发者可以学习如何在实际项目中应用这些技术。 总之,串口设备枚举类是串口通信...

    vc 根据硬件变动枚举所有串口comport

    7. **代码结构**:一个简单的实现可能包括主程序(如main函数)、消息处理函数(处理`WM_DEVICECHANGE`)和枚举串口的辅助函数。枚举函数会遍历系统中所有可能的COM端口,并将它们的信息存储在一个数据结构中,以便...

    简单的C++串口示例

    在本文中,我们将深入探讨如何使用C++进行串口通信,特别是通过MFC(Microsoft Foundation Classes)框架构建一个简单的串口示例应用。这个示例程序涵盖了从检测可用串口到配置串口属性,再到开启、关闭串口以及处理...

    BCB6.0四种方法枚举电脑串口

    在本文中,我们将深入探讨如何在BCB6.0(Borland C++ Builder 6.0)环境下使用四种不同的方法来枚举计算机上的串行端口。串口,也称为COM口,是计算机硬件中用于与外部设备进行串行通信的接口。在开发需要与串口交互...

Global site tag (gtag.js) - Google Analytics