我有一些遗留代码,它通过调用EnumPorts()
函数然后过滤以“COM”开头的端口名称来提供PC上可用COM端口的列表。
出于测试目的,如果我可以将此代码用于com0com之类的代码,它将非常有用,它提供了作为零调制解调器循环在一起的虚拟COM端口对。
然而EnumPorts()
函数找不到com0com端口(即使没有过滤“COM”)。 HyperTerminal和SysInternals PortMon都可以看到它们,所以我确定它安装正确。
那么还有其他一些Win32功能可以提供可用串口的确切列表吗?
答案 0 :(得分:76)
Nick D建议的EnumSerialPorts v1.20使用 9 种不同的方法列出串口!我们肯定不会做出选择,但结果似乎有所不同。
为了省去其他人的麻烦,我会在这里列出并表明他们在我的电脑上找到com0com
端口的成功(XP专业版SP2):
CreateFile(“COM”+ 1-> 255) ✔找到com0com端口,耗时234ms。
<强> QueryDosDevice()强>
✔找到com0com端口,耗时0ms。
GetDefaultCommConfig(“COM”+ 1-&gt; 255)
✔找到com0com端口,耗时235毫秒。
使用SETUPAPI.DLL调用“SetupAPI1”
✔发现com0com端口,也报告“友好名称”,耗时15ms。
使用SETUPAPI.DLL调用“SetupAPI2”
✘没有找到com0com端口,报告“友好名称”,耗时32ms。
<强> EnumPorts()强>
✘报告了一些非COM端口,没有找到com0com端口,耗时15ms。
使用WMI通话
✔发现com0com端口,也报告“友好名称”,耗时47ms。
使用MSPORTS.DLL调用的COM数据库
✔/✘报告了一些非COM端口,找到了com0com端口,耗时16ms。
迭代注册表项HKEY_LOCAL_MACHINE \ HARDWARE \ DEVICEMAP \ SERIALCOMM
✔找到com0com端口,耗时0ms。这显然是SysInternals PortMon使用的。
根据这些结果,我认为WMI方法可能最适合我的要求,因为它相对较快,作为奖励,它还提供了友好的名称(例如“通信端口(COM1)”,“com0com - 串口仿真器”)
答案 1 :(得分:11)
看起来这不是一项简单的任务。
看看这个:EnumSerialPorts v1.20
答案 2 :(得分:5)
您可以循环播放例如1到50并尝试打开每个端口。如果端口可用,则打开将起作用。如果端口正在使用中,您将收到共享错误。如果未安装端口,则会收到文件未找到错误。
打开端口使用 CreateFile API:
HANDLE Port = CreateFile(
"\\\\.\\COM1",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
然后检查结果。
答案 3 :(得分:1)
我已经将PJ Naughter的EnumSerialPorts重组为更便携和个性化的形式,这更有用。
为了更好地兼容,我使用C而不是C ++。
如果您需要或对此感兴趣,请访问我的博客中的the post。
答案 4 :(得分:1)
就我而言,我需要全名和COM端口地址。我有物理串口,USB串口和com0com虚拟串口。
就像接受的答案所示,我使用WMI调用。 SELECT * FROM Win32_PnPEntity
找到所有设备。它返回这样的物理设备,地址可以从Caption
解析:
Serial Port for Barcode Scanner (COM13)
但是,对于com0com端口Caption
是这样的(没有地址):
com0com - serial port emulator
SELECT * FROM Win32_SerialPort
返回地址(DeviceID
)以及全名(Name
)。但是,它只能找到物理串行端口和com0com端口,而不是USB串行端口。
所以最后,我需要两个WMI调用:SELECT * FROM Win32_SerialPort
(地址为DeviceID
)和SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%(COM%'
(地址可以从Caption
解析)。我缩小了Win32_PnPEntity
来电,因为它只需要找到第一次通话中找不到的设备。