如何获得Win32中的可用串行端口列表?
我有一些遗留代码,通过调用EnumPorts()
函数,然后筛选以“COM”开头的端口名称,提供PC上可用COM端口的列表。
出于testing的目的,如果我可以使用com0com这样的代码来提供这些代码,它将提供成对的虚拟COM端口作为一个空调制解调器。
但是,EnumPorts EnumPorts()
函数找不到com0com端口(即使没有过滤“COM”)。 超级terminal和SysInternals PortMon都可以看到他们,所以我确定它安装正确。
那么还有其他一些Win32函数提供了可用的串行端口的权威列表吗?
Nick Dbuild议的EnumSerialPorts v1.20使用九种不同的方法列出串行端口! 虽然结果似乎有所不同,但我们当然并不缺乏select。
为了节省他人的麻烦,我将在这里列出他们,并指出他们在我的电脑(XP Pro SP2)上findcom0com
端口的成功:
-
如Wael Dalloulbuild议的CreateFile(“COM”+ 1-> 255)
✔findcom0com端口,花了234ms。 -
QueryDosDevice()
✔findcom0com端口,花了0ms。 -
GetDefaultCommConfig(“COM”+ 1-> 255)
✔findcom0com端口,花了235ms。 -
使用SETUPAPI.DLL调用“SetupAPI1”
✔发现com0com端口,也报“友好名称”,花了15ms。 -
使用SETUPAPI.DLL调用“SetupAPI2”
✘没有findcom0com端口,报告“友好的名字”,花了32毫秒。 -
EnumPorts()
✘报告了一些非COM端口,没有findcom0com端口,花了15ms。 -
使用WMI调用
✔发现com0com的端口,也报“友好的名字”,耗时47毫秒。 -
COM数据库使用调用MSPORTS.DLL
✔/✘报告了一些非COM端口,发现com0com端口,耗时16ms。 -
迭代registry项HKEY_LOCAL_MACHINE \ HARDWARE \ DEVICEMAP \ SERIALCOMM
✔findcom0com端口,花了0ms。 这显然是SysInternals PortMon使用的。
基于这些结果,我认为WMI方法可能最适合我的要求,因为它相对较快,作为一个奖励它还给出友好的名称(例如“通信端口(COM1)”,“com0com – 串行端口仿真器”)。
看来,这不是一个简单的任务。
看看这个: EnumSerialPorts v1.20
你可以循环例如从1到50,并尝试打开每个端口。 如果端口可用,则打开将工作。 如果端口正在使用中,则会出现共享错误。 如果端口没有安装,你会得到一个文件未find错误。
打开该端口使用CreateFile API:
HANDLE Port = CreateFile( "\\\\.\\COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
然后检查结果。
我已经将PJ Naugh的EnumSerialPorts重组为更便携的个人forms,这是更有用的。
为了更好的兼容性,我使用C而不是C ++。
如果您需要或有兴趣,请访问我的博客文章。
在我的情况下,我需要全名和COM端口地址。 我有物理串行端口,USB串行端口和com0com虚拟串行端口。
就像接受的答案所暗示的那样,我使用WMI调用。 SELECT * FROM Win32_PnPEntity
查找所有设备。 它返回像这样的物理设备,地址可以从Caption
parsing:
Serial Port for Barcode Scanner (COM13)
但是,对于com0com端口Caption
是这样的(没有地址):
com0com - serial port emulator
SELECT * FROM Win32_SerialPort
返回地址( DeviceID
)以及全名( Name
)。 但是,它只能find物理串行端口和com0com端口,而不是USB串行端口。
所以最后,我需要两个WMI调用: SELECT * FROM Win32_SerialPort
(地址是DeviceID
)和SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%(COM%'
(地址可以从Caption
parsing)我已经缩小了Win32_PnPEntity
调用,因为它只需要查找在第一次调用中找不到的设备。