You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否无需打开连接获取FTDI设备端口号?附相关代码问询

无需打开FTDI设备即可获取端口号及描述信息

当然可以不用打开FTDI设备就能获取它的COM端口号!你提到的FT_DEVICE_LIST_INFO_NODE结构体确实没有包含端口号,这是因为该结构体主要存储FTDI设备的硬件层面信息(比如VID/PID、序列号、描述等),而COM端口号是Windows系统为设备分配的逻辑标识,不属于FTDI驱动直接维护的核心设备元数据。

至于为什么FT_GetComPortNumber需要打开设备句柄——这是FTDI D2XX API的设计选择,它通过与打开的设备驱动实例交互来获取端口号,但我们完全可以通过Windows系统API绕开这个限制,直接从系统设备信息中提取所需内容,全程无需调用FT_Open/FT_Close。

替代方案:使用Windows SetupAPI枚举FTDI设备

SetupAPI是Windows提供的用于枚举和配置硬件设备的原生API,我们可以用它定位所有FTDI设备,直接读取它们的COM端口号和描述信息,完全不需要依赖FTDI的D2XX库打开端口。

以下是实现代码示例:

#include <iostream>
#include <windows.h>
#include <setupapi.h>
#include <initguid.h>
#include <cstring>

// 串口设备的GUID,用于定位系统中的串口设备接口
DEFINE_GUID(GUID_DEVINTERFACE_COMPORT, 0x86e0d1e0L, 0x8089, 0x11d0, 0x9ce4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73);

void EnumerateFTDIPorts() {
    // 获取当前存在的所有串口设备接口列表
    HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_COMPORT, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (hDevInfo == INVALID_HANDLE_VALUE) {
        std::cout << "SetupDiGetClassDevs failed: " << GetLastError() << std::endl;
        return;
    }

    SP_DEVICE_INTERFACE_DATA deviceInterfaceData = {0};
    deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

    // 遍历每个串口设备接口
    for (DWORD i = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVINTERFACE_COMPORT, i, &deviceInterfaceData); i++) {
        DWORD requiredSize = 0;
        // 先查询获取设备详情所需的缓冲区大小
        SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, NULL, 0, &requiredSize, NULL);
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            std::cout << "SetupDiGetDeviceInterfaceDetail size check failed: " << GetLastError() << std::endl;
            continue;
        }

        // 分配缓冲区存储设备详情
        PSP_DEVICE_INTERFACE_DETAIL_DATA pDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiredSize);
        if (!pDetailData) {
            std::cout << "Failed to allocate memory for device detail data" << std::endl;
            continue;
        }
        pDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

        SP_DEVINFO_DATA devInfoData = {0};
        devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

        if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, pDetailData, requiredSize, NULL, &devInfoData)) {
            // 读取设备硬件ID,筛选FTDI设备(FTDI的VID为0x0403)
            DWORD dataType;
            BYTE vidPidBuffer[256];
            if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_HARDWAREID, &dataType, vidPidBuffer, sizeof(vidPidBuffer), NULL)) {
                char* hardwareId = (char*)vidPidBuffer;
                if (strstr(hardwareId, "VID_0403") != NULL) {
                    // 从设备路径中提取COM端口号
                    char* comPort = strstr(pDetailData->DevicePath, "COM");
                    if (comPort) {
                        // 读取设备友好描述信息
                        char description[256];
                        if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_FRIENDLYNAME, &dataType, (BYTE*)description, sizeof(description), NULL)) {
                            std::cout << comPort << " is " << description << std::endl;
                        } else {
                            std::cout << comPort << " is [No description available]" << std::endl;
                        }
                    }
                }
            }
        } else {
            std::cout << "SetupDiGetDeviceInterfaceDetail failed: " << GetLastError() << std::endl;
        }

        free(pDetailData);
    }

    SetupDiDestroyDeviceInfoList(hDevInfo);
}

int main() {
    EnumerateFTDIPorts();
    return 0;
}

代码说明

  1. 我们通过SetupDiGetClassDevs获取系统中所有当前可用的串口设备接口
  2. 遍历每个设备接口,通过硬件ID中的VID_0403筛选出FTDI设备
  3. 直接从设备详情中提取COM端口号和友好描述,全程无需打开设备或调用FTDI的D2XX接口

这种方法和你提到的Win32 API枚举逻辑一致,完全绕开了FTDI API需要打开设备的限制,能高效获取所需信息。

内容的提问来源于stack exchange,提问作者jpo38

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 21:52:27