我想列出 FTDI 端口及其描述,这是我的程序:
#include <iostream>
#include "ftd2xx.h"
int main( int argc, char* argv[] )
{
DWORD numDevs = 0, i = 0;
FT_DEVICE_LIST_INFO_NODE *ftDevList = NULL;
FT_STATUS ftStatus;
/* Get the number of FTDI D2XX devices connected to the system.
* This also trigs in the driver the creation of a list which we later get
* using FT_GetDeviceInfoList(). */
if( (ftStatus = FT_CreateDeviceInfoList(&numDevs)) != FT_OK )
{
std::cout << "FT_CreateDeviceInfoList failed with error " << ftStatus << std::endl;
return 1;
}
if( numDevs != 0 )
{
/* Ask the FTDI USB driver the list of all numDevs FTDI D2XX devices which
* are plugged in the PC: */
ftDevList = (FT_DEVICE_LIST_INFO_NODE *)
malloc(numDevs * sizeof(FT_DEVICE_LIST_INFO_NODE));
if ( !ftDevList )
{
std::cout << "Could not get device list" << std::endl;
return 1;
}
if ( (ftStatus = FT_GetDeviceInfoList(ftDevList, &numDevs)) != FT_OK )
{
std::cout << "FT_GetDeviceInfoList failed with error " << ftStatus << std::endl;
return 1;
}
for ( i = 0 ; i < numDevs ; i++ )
{
FT_HANDLE ftOpenHandle;
if ((ftStatus = FT_Open(i,&ftOpenHandle)) == FT_OK)
{
LONG lComPortNumber = 0;
if ( (ftStatus = FT_GetComPortNumber(ftOpenHandle,&lComPortNumber)) == FT_OK)
{
if (lComPortNumber == -1)
{
// No COM port assigned
}
else
{
std::cout << "COM" << lComPortNumber << " is " << ftDevList[i].Description << std::endl;
}
}
else
{
std::cout << "FT_GetComPortNumber failed with error " << ftStatus << std::endl;
return 1;
}
FT_Close(ftOpenHandle);
}
else
{
std::cout << "FT_Open failed with error " << ftStatus << std::endl;
return 1;
}
}
free( ftDevList );
}
// else: No need to build this empty list. We have all the information: "there is
// no USB FTDI device plugged in the PC".
return 0;
}
但是,正如您所看到的,这会打开端口
FT_Open
/FT_Close
。我只是很惊讶端口号不是 FT_DEVICE_LIST_INFO_NODE
的一部分...为什么我需要打开端口来检索这些基本信息?例如,使用 WIN32 API,可以在不“打开”的情况下枚举端口...有没有办法使用 FTDI 驱动程序来做到这一点?
简而言之,使用 FTDI DLL,只有在打开后才能读取 COM 端口字符串。 此外,如果由另一个进程打开,FT_CreateDeviceInfoList 不会返回任何内容。简直没用!
但是..有一个技巧, 您可以随时访问设备管理器中看到的内容,而不会“中断”。 在这里您可以找到 COM 端口和 FTDI 序列号的缓存副本 --> 即使连接打开时<--
步骤:
我不知道在 C++ 中如何做到这一点,但是在 Windows 上的 C# 中,你明白了..
using System.Management;
...
public class DeviceManagerInfoStruct
{
public required string? Caption { get; set; }
public required string? Service { get; set; }
public required string? DeviceID { get; set; }
}
...
IEnumerable<DeviceManagerInfoStruct?> ports;
// Build a query that selects all devices where PNPClass=="Ports" (Class in device manager)
// https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-pnpentity#properties
using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE PNPClass like 'Ports'"))
{
// Extract all records found in the device manager under 'Ports (LPT & COM)'
var Ports_LPT_COM = searcher.Get().Cast<ManagementBaseObject>().ToList();
// Populate the ports struct with DeviceManager information
ports = Ports_LPT_COM.Select( dm_info =>
new DeviceManagerInfo
{
Caption = dm_info["Caption"]?.ToString(),
Service = dm_info["Service"]?.ToString(),
DeviceID = dm_info["DeviceID"]?.ToString()
} );
}
// Print results
foreach (var port in ports)
Console.WriteLine($"Caption={port?.Caption}, Service={port?.Service}, DeviceID={port?.DeviceID}");
如果Service==FTSER2K,则它是FTDI。 您在 [Caption] 中有 COM 编号,在 [DeviceID] 中有序列号。
我得到以下结果。
Caption=ECP Printer Port (LPT1), Service=Parport, DeviceID=ACPI\PNP0401\5
Caption=Communications Port (COM1), Service=Serial, DeviceID=ACPI\PNP0501\0
Caption=USB Serial Port (COM9), Service=FTSER2K, DeviceID=FTDIBUS\VID_0403+PID_6001+FTDWGWNQA\0000
Caption=USB Serial Port (COM13), Service=FTSER2K, DeviceID=FTDIBUS\VID_0403+PID_6014+FT9UOLFJA\0000
Caption=Standard Serial over Bluetooth link (COM6), Service=BTHMODEM, DeviceID=BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0002\8&31A2A89E&0&D8373B6C9E26_C00000000
Caption=Standard Serial over Bluetooth link (COM7), Service=BTHMODEM, DeviceID=BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0000\8&31A2A89E&0&000000000000_00000000
Caption=USB Serial Port (COM18), Service=FTSER2K, DeviceID=FTDIBUS\VID_0403+PID_6010+FT9OETCDA\0000
Caption=USB Serial Port (COM19), Service=FTSER2K, DeviceID=FTDIBUS\VID_0403+PID_6010+FT9OETCDB\0000