I am trying to find the correct way of finding the COM port name if I know the PID and VID. So far I wrote the workaround but i do not believe that there is no more elegant and correct way. BTW (I know that I can use REGEX). This was written only to test the workaround.
I know that there is a lots of space for improvements and I am not asking for a code review
Any ideas are more than welcome :)
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; }
}
}
It does the job - but I di not like it