21xrx.com
2025-07-11 23:22:47 Friday
文章检索 我的文章 写文章
C++如何获取本机的COM口列表
2023-06-29 08:30:19 深夜i     49     0
C++ 获取 本机 COM口列表

在C++中,获取本机的COM口列表是一个常见的需求。COM口是计算机与外部设备通信的端口,包括串行口和并行口。在Windows操作系统中,COM口一般以“COM1”、“COM2”等命名。下面我们将介绍如何在C++中获取本机的COM口列表。

首先,我们需要使用Windows API函数“CreateFile”来打开COM口。这个函数能返回一个文件句柄,如果COM口不存在或已被占用,则返回无效句柄。我们可以使用这个函数来逐个尝试打开每个COM口,从而获取COM口列表。以下是获取COM口列表的C++代码:

#include <windows.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void GetComPorts(vector<string>& ports)
{
  for (int i = 1; i <= 255; i++)
  {
    string portName = "COM" + to_string(i);
    HANDLE hComm = CreateFile(
      portName.c_str(),
      GENERIC_READ | GENERIC_WRITE,
      0,
      NULL,
      OPEN_EXISTING,
      0,
      NULL
    );
    if (hComm != INVALID_HANDLE_VALUE)
    {
      ports.push_back(portName);
      CloseHandle(hComm);
    }
  }
}
int main()
{
  vector<string> ports;
  GetComPorts(ports);
  for (int i = 0; i < ports.size(); i++)
  {
    cout << ports[i] << endl;
  }
  return 0;
}

在这个代码中,我们使用一个“GetComPorts”函数来获取COM口列表。我们尝试打开从“COM1”到“COM255”的所有端口,对于打开成功的端口,将它们的名称添加到一个vector容器里面。最后我们遍历这个vector容器,并输出所有COM口的名称。

需要注意的是,在获取COM口列表时,一些已经被占用的COM口可能无法打开。因此,我们需要将这些COM口剔除。一种方法是使用Windows API函数“EnumPorts”来获取所有打印机端口,并将它们从COM口列表中剔除。下面是使用“EnumPorts”函数的代码:

void GetComPorts(vector<string>& ports)
{
  for (int i = 1; i <= 255; i++)
  {
    string portName = "COM" + to_string(i);
    HANDLE hComm = CreateFile(
      portName.c_str(),
      GENERIC_READ | GENERIC_WRITE,
      0,
      NULL,
      OPEN_EXISTING,
      0,
      NULL
    );
    if (hComm != INVALID_HANDLE_VALUE)
    {
      CloseHandle(hComm);
      DWORD numBytesNeeded = 0;
      DWORD numPorts = 0;
      if (EnumPorts(NULL, 2, NULL, 0, &numBytesNeeded, &numPorts))
      
        continue;
      
      LPBYTE pPortInfo = new BYTE[numBytesNeeded];
      if (EnumPorts(NULL, 2, pPortInfo, numBytesNeeded, &numBytesNeeded, &numPorts))
      {
        for (int j = 0; j < numPorts; j++)
        {
          PPORT_INFO_2 pPortInfo2 = (PPORT_INFO_2)pPortInfo;
          if (_stricmp(pPortInfo2[j].pPortName, portName.c_str()) == 0)
          
            goto end_loop;
          
        }
        ports.push_back(portName);
      }
      end_loop:
      delete[] pPortInfo;
    }
  }
}

在这个代码中,我们使用了两次“EnumPorts”函数。第一次调用该函数只是为了获取需要分配的内存大小,第二次才是真正获取打印机端口列表。接下来我们遍历打印机端口列表,如果发现COM口名称与打印机端口列表中的名称相同,则将该端口从COM口列表中剔除。

综上所述,我们可以使用“CreateFile”函数遍历所有可能的COM口来获取COM口列表,同时也可以使用“EnumPorts”函数剔除因被占用而无法打开的COM口。

  
  

评论区

    相似文章