65.9K
CodeProject 正在变化。 阅读更多。
Home

另一个串口枚举器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.35/5 (21投票s)

2001年7月17日

4分钟阅读

viewsIcon

239969

downloadIcon

9812

一个用于枚举串行端口的库,可在 9x、NT 4.0 和 2000、XP 和 CE 平台下工作

引言

ListPorts 是一个列出系统中所有可用串行端口的函数,并附带一些描述性文本,适合在用户界面中显示,而不是使用“COM1”、“COM2”等简短的名称。您可以在系统调制解调器属性对话框的“端口”组合框中看到一个示例。

PJ Naughter 已经编写了一些用于此目的的代码(请参阅 CodeProject 上的 EnumSerialPorts,或点击 此处 查看他库的最新版本)。 IMHO,与 PJ Naughter 的方法相比,ListPorts 具有一些优势:

  • 它不依赖 MFC,
  • 它似乎能更好地处理非标准端口(虚拟、红外线),
  • 为每个端口提供了描述性文本,
  • 可在 Windows CE 上工作。

无论如何,我们不想因此被指责鼓吹:请比较这两种方法并自行做出选择。

用法

listports.h 头文件提供了以下 C 语言定义:

typedef struct
{
  LPCTSTR lpPortName;
  LPCTSTR lpFriendlyName;
  LPCTSTR lpTechnology;
}LISTPORTS_PORTINFO;

typedef BOOL (CALLBACK* LISTPORTS_CALLBACK)(LPVOID lpCallbackValue,
                                            LISTPORTS_PORTINFO* lpPortInfo);

BOOL ListPorts(LISTPORTS_CALLBACK lpCallback,LPVOID lpCallbackValue);

LISTPORTS_PORTINFO 包含有关特定串行端口的信息:lpPortName 包含可用于通过 CreateFile() 获取端口句柄的标准“COMn”字符串,而 lpFriendlyName 包含端口的更完整描述(例如,“红外通信端口 (COM4)”)。在支持该功能的系统上,lpTechnology 指示串行端口运行所基于的技术:典型值包括“BIOS”、“INFRARED”、“USB”等。

LISTPORTS_CALLBACK 定义了一个用户提供的回调例程,该例程在 ListPorts 的连续调用中接收系统中每个可用串行端口的信息。在回调中执行适合您需求的操作:将信息转储到控制台、将其填充到列表框或存储以供将来使用。请注意,在回调返回后,LISTPORTS_PORTINFO 中的字符串将不再有效:因此,如果您打算存储这些值,则应创建其私有副本。

如果您的回调返回 FALSE,则枚举将被中止。

ListPorts 接受一个名为 lpCallbackValue 的附加参数。该参数由库作为不透明数据处理并传递给您的回调,以便您可以将其用于特定目的(例如,区分对 ListPorts 的不同调用或存储指向负责使用结果的某个对象的指针)。这在许多基于回调的 API 中是一种标准技术。

有关该库的特别简单的使用示例,请参阅演示项目。

跨平台问题

ListPorts 可在以下操作系统上运行:

  • Windows 95、98、ME
  • Windows NT 4.0
  • Windows 2000、XP
  • Windows CE

但根据操作系统的不同,存在一些缺点。在 NT 4.0 上,我们未能找到串行端口的描述文本(实际上我们怀疑 NT 4.0 没有这些):而是提供原始的“COMn”字符串。lpTechnology 字段在 NT 4.0 和 Windows CE 平台上不可用。

Windows CE 设备具有操作系统底层的高度定制化,可能不适合 ListPorts 使用的算法:然而,我们的实际测试表明,ListPorts 在 Windows CE 中遗漏某些端口的概率非常低。

Unicode

在定义了宏 UNICODE_UNICODE 的情况下,代码可以很好地在 Unicode 下编译和运行。

技术

如果您对库的内部机制不感兴趣,请跳过此部分。

ListPorts 通过扫描注册表来查找系统中可用的串行端口信息。在 Windows 9x 平台上,已安装设备的信息存储在 HKEY_LOCAL_MACHINE\Enum 键下。枚举树有三个级别,设备在最深一级进行描述。例如,一个内置于主板并被 BIOS 识别的标准 UART 串行端口可能存储如下:

HKLM\ENUM
  |-BIOS
    |-*PNP0501
      |-0D (or any other value, this is not important for us)
        · CLASS=        "Ports"
        · PORTNAME=     "COM1"
        · FRIENDLYNAME= "Communications Port (COM1)"

CLASS 值标识设备类型,并被 ListPorts 用来定位通信端口。

在 Windows 2000/XP 上,情况非常相似,只是枚举树位于 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Enum,并且 CLASS 已被基于 COM 唯一标识符的 CLASSGUID 标识符取代。

Windows NT 4.0 缺少一个完全开发的设备枚举树。串行端口的信息可以在 HKEY_LOCAL_MACHINE\Hardware\DEVICEMAP\SERIALCOMM 中找到,但这里没有提供 FRIENDLYNAME

Windows CE 将串行端口条目与其他通信端口一起存储在 HKLM\Drivers\BuiltIn 下。

该库使用的方法在 listports.c 文件中的代码注释中进行了更详细的讨论。

2.0 版本新增(2005 年 8 月)

  • 新增 lpTechnology 字段。
  • 支持 Windows CE 平台。
© . All rights reserved.