C++如何查询COM端口设备 判定特定设备是否连接
特定COM端口设备连接判定方法
现有方案局限
当前通过QueryDosDevice接口枚举0-255号COM端口的实现代码如下:
TCHAR lpTargetPath[5000]; for (int i = 0; i < 255; i++) // checking ports from COM0 to COM255 { std::string str = "COM" + std::to_string(i); DWORD test = QueryDosDevice(str.c_str(), lpTargetPath, 5000); // 返回值为0时表示未找到对应设备,非0时返回存入缓冲区的字符数 if (test != 0) { std::cout << str << ": " << lpTargetPath << std::endl; } if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { cout << "buffer error" << endl; } }
该方案只能获取通用设备路径,典型返回结果如下:
COM3: \Device\Serial0 COM6: \Device\USBSER000
这类信息不包含设备唯一特征,且系统中USB串口默认显示名称均为USB Serial Device(COMx),没有有效识别参考价值,无法判定特定设备是否连接。
可行实现路径
优先选择直接读取系统存储的设备唯一标识,不需要轮询端口读取设备特征签名,常用实现方式为调用SetupAPI系列系统接口,具体逻辑如下:
- 调用
SetupDiGetClassDevs传入串口设备接口GUID{86E0D1E0-8089-11D0-9CE4-08003BE30173},获取当前所有已注册串口设备的信息集合 - 遍历集合内的设备,依次调用
SetupDiEnumDeviceInterfaces、SetupDiGetDeviceInterfaceDetail获取每个设备的详细属性,既能拿到设备对应的COM端口号,也能直接读取设备的硬件ID、厂商ID(VID)、产品ID(PID)、USB序列号等唯一标识 - 将读取到的标识和目标设备的已知特征做比对,即可判定目标设备是否连接、对应哪个COM端口。绝大多数USB转串口设备的设备实例路径格式为
USB\VID_xxxx&PID_xxxx\<设备唯一序列号>,只要设备固件写入了唯一序列号,该值可直接作为设备匹配的依据,识别准确率100%。
如果不想调用SetupAPI,也可以通过读取注册表关联COM端口和设备信息:
- 注册表路径
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM下存储了所有当前存在的COM端口和设备内部名的映射 - 再到
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB路径下匹配对应设备的条目,即可读取到设备的VID/PID、序列号等属性,该方法需要更高的系统权限,兼容性弱于SetupAPI方案,不做优先推荐。
方案选型参考
只有当目标设备未写入唯一USB序列号、且硬件VID/PID和同芯片其他设备完全一致无法区分时,才需要考虑轮询打开空闲COM端口、发送设备识别指令读取返回特征签名的方式做判定。这种方式需要占用串口,若串口被其他程序占用则无法完成识别,仅作为备选方案使用。
内容的提问来源于stack exchange,提问作者user16541120
相关产品推荐
相关产品推荐

