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

如何在C#中通过PID和VID查找虚拟COM端口名称

通过PID和VID查找COM端口的更优实现思路

我正在寻找通过PID和VID查找COM端口名称的正确方法。目前我已经写了一个临时方案能跑起来,但总觉得应该有更优雅、更规范的实现方式。(注:我知道可以用正则表达式,当前代码只是用来测试的临时版本)。我清楚这段代码还有很大改进空间,不是来求代码审查的,只是想听听大家有没有更好的思路😊

以下是我目前的实现代码:

namespace ConsoleApplication1 { using System; using System.Globalization; using System.Collections.Generic; using System.Management; using System.Reflection; class Program { static void Main(string[] args) { VCOMDetect VCOMPorts = new VCOMDetect(0x0483, 0xA27D); Console.WriteLine("BootPort: {0}", VCOMPorts.BootPort() ?? "Not detected"); Console.WriteLine("Oscilloscope Port: {0}", VCOMPorts.OscilloscopePort() ?? "Not detected"); Console.WriteLine("Serial/USB Port: {0}", VCOMPorts.SerialPort() ?? "Not detected"); Console.WriteLine("Programming Port: {0}", VCOMPorts.ProgPort() ?? "Not detected"); Console.Read(); } } class VCOMDetect { private const string USB_BOOTLOADER_SERIAL = "000000000b00"; private const string USB_OSCILLOSCOPE_SERIAL = "000000000c00"; private const string USB_VCOM_SERIAL = "000000000d00"; private const string USB_PRG_SERIAL = "000000000e00"; private List<VCOM_USBDeviceInfo> PortsList; public VCOMDetect(UInt16 vid, UInt16 pid) { PortsList = GetUSBDevices(vid, pid); } public string BootPort() { foreach(VCOM_USBDeviceInfo VCOM in PortsList) { if (VCOM.Serial.ToLower() == USB_BOOTLOADER_SERIAL.ToLower()) return VCOM.COMPort; } return null; } public string OscilloscopePort() { foreach (VCOM_USBDeviceInfo VCOM in PortsList) { if (VCOM.Serial.ToLower() == USB_OSCILLOSCOPE_SERIAL.ToLower()) return VCOM.COMPort; } return null; } public string SerialPort() { foreach (VCOM_USBDeviceInfo VCOM in PortsList) { if (VCOM.Serial.ToLower() == USB_VCOM_SERIAL.ToLower()) return VCOM.COMPort; } return null; } public string ProgPort() { foreach (VCOM_USBDeviceInfo VCOM in PortsList) { if (VCOM.Serial.ToLower() == USB_PRG_SERIAL.ToLower()) return VCOM.COMPort; } return null; } private List<VCOM_USBDeviceInfo> GetUSBDevices(UInt16 vid, UInt16 pid) { List<VCOM_USBDeviceInfo> VCOM_devices = new List<VCOM_USBDeviceInfo>(); ManagementObjectCollection collection; using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_PnPEntity")) collection = searcher.Get(); foreach (var device in collection) { var USBInfo = new VCOM_USBDeviceInfo((string)device.GetPropertyValue("DeviceID")); if (USBInfo.PID == 0 || USBInfo.VID == 0) continue; if (USBInfo.PID != pid || USBInfo.VID != vid) continue; USBInfo.Caption = (string)device.GetPropertyValue("Caption"); if (USBInfo.COMPort == "") continue; USBInfo.PnpDeviceID = (string)device.GetPropertyValue("PNPDeviceID"); USBInfo.Description = (string)device.GetPropertyValue("Description"); VCOM_devices.Add(USBInfo); } collection.Dispose(); return VCOM_devices; } } class VCOM_USBDeviceInfo { private UInt16 _PID, _VID; private string _Caption; private void _ResetData() { this.PID = 0; this.VID = 0; this.COMnumber = -1; this.COMPort = ""; this.Serial = ""; } public VCOM_USBDeviceInfo(string DeviceID) { int VIDIndex = DeviceID.IndexOf("VID_"); int PIDIndex = DeviceID.IndexOf("PID_"); int VIDIndexEnd = -1; int PIDIndexEnd = -1; string PIDSubstring, VIDSubstring; if (PIDIndex == -1 || VIDIndex == -1) { _ResetData(); } else { bool result = true; PIDSubstring = DeviceID.Substring(PIDIndex + 4); VIDSubstring = DeviceID.Substring(VIDIndex + 4); PIDIndexEnd = PIDSubstring.IndexOf("\\"); VIDIndexEnd = VIDSubstring.IndexOf("&"); if(PIDIndexEnd == -1 || VIDIndexEnd == -1) { _ResetData(); } else { result = result && UInt16.TryParse(PIDSubstring.Substring(0, PIDIndexEnd), NumberStyles.AllowHexSpecifier, null, out _PID) && UInt16.TryParse(VIDSubstring.Substring(0, VIDIndexEnd), NumberStyles.AllowHexSpecifier, null, out _VID); if(!result) { _ResetData(); } else { PID = _PID; VID = _VID; Serial = PIDSubstring.Substring(PIDIndexEnd + 1); } } } } public string DeviceID { get; set; } public string PnpDeviceID { get; set; } public string Description { get; set; } public string Caption { get { return _Caption; } set { int COMindex = value.IndexOf("(COM"); string tmpCOMPort = COMindex == -1 ? "" : value.Substring(COMindex + 1, 4); if(COMPort == null || COMPort.Length == 0) { COMPort = tmpCOMPort; } else { if(COMPort != tmpCOMPort) { Console.WriteLine("Inconsistent COM port information"); } } _Caption = value; } } public UInt16 PID { get; set; } public UInt16 VID { get; set; } public string Serial { get; set; } public int COMnumber { get; set; } public string COMPort { get; set; } } }

这段代码确实能实现功能,但我总觉得不够满意,希望能找到更合理的实现方式。

设备管理器中的COM端口信息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:07:17