mirror of
https://github.com/fasteddy516/SimplySerial.git
synced 2024-11-24 10:04:35 +00:00
Re-worked serial port and CircuitPython detection
This commit is contained in:
parent
6bd3b9c589
commit
75d6bb250e
@ -385,14 +385,15 @@ namespace SimplySerial
|
|||||||
if (availablePorts.Count >= 1)
|
if (availablePorts.Count >= 1)
|
||||||
{
|
{
|
||||||
Console.WriteLine("\nPORT\tVID\tPID\tDESCRIPTION");
|
Console.WriteLine("\nPORT\tVID\tPID\tDESCRIPTION");
|
||||||
Console.WriteLine("------------------------------------------------------------");
|
Console.WriteLine("----------------------------------------------------------------------");
|
||||||
foreach (ComPort p in availablePorts)
|
foreach (ComPort p in availablePorts)
|
||||||
{
|
{
|
||||||
Console.WriteLine("{0}\t{1}\t{2}\t{3}",
|
Console.WriteLine("{0}\t{1}\t{2}\t{3} {4}",
|
||||||
p.name,
|
p.name,
|
||||||
p.vid,
|
p.vid,
|
||||||
p.pid,
|
p.pid,
|
||||||
(p.board.isCircuitPython) ? (p.board.make + " " + p.board.model) : p.description
|
(p.board.isCircuitPython) ? (p.board.make + " " + p.board.model) : p.description,
|
||||||
|
((p.busDescription.Length > 0) && !p.description.StartsWith(p.busDescription)) ? ("[" + p.busDescription + "]") : ""
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Console.WriteLine("");
|
Console.WriteLine("");
|
||||||
@ -648,6 +649,7 @@ namespace SimplySerial
|
|||||||
public string vid;
|
public string vid;
|
||||||
public string pid;
|
public string pid;
|
||||||
public string description;
|
public string description;
|
||||||
|
public string busDescription;
|
||||||
public Board board;
|
public Board board;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,6 +661,8 @@ namespace SimplySerial
|
|||||||
/// https://github.com/freakone/serial-reader
|
/// https://github.com/freakone/serial-reader
|
||||||
/// Some modifications were based on this stackoverflow thread:
|
/// Some modifications were based on this stackoverflow thread:
|
||||||
/// https://stackoverflow.com/questions/11458835/finding-information-about-all-serial-devices-connected-through-usb-in-c-sharp
|
/// https://stackoverflow.com/questions/11458835/finding-information-about-all-serial-devices-connected-through-usb-in-c-sharp
|
||||||
|
/// Hardware Bus Description through WMI is based on Simon Mourier's answer on this stackoverflow thread:
|
||||||
|
/// https://stackoverflow.com/questions/69362886/get-devpkey-device-busreporteddevicedesc-from-win32-pnpentity-in-c-sharp
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>List of available serial ports</returns>
|
/// <returns>List of available serial ports</returns>
|
||||||
private static List<ComPort> GetSerialPorts()
|
private static List<ComPort> GetSerialPorts()
|
||||||
@ -666,20 +670,36 @@ namespace SimplySerial
|
|||||||
const string vidPattern = @"VID_([0-9A-F]{4})";
|
const string vidPattern = @"VID_([0-9A-F]{4})";
|
||||||
const string pidPattern = @"PID_([0-9A-F]{4})";
|
const string pidPattern = @"PID_([0-9A-F]{4})";
|
||||||
const string namePattern = @"(?<=\()COM[0-9]{1,3}(?=\)$)";
|
const string namePattern = @"(?<=\()COM[0-9]{1,3}(?=\)$)";
|
||||||
|
const string query = "SELECT * FROM Win32_PnPEntity WHERE ClassGuid=\"{4d36e978-e325-11ce-bfc1-08002be10318}\"";
|
||||||
|
|
||||||
using (var searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PnPEntity WHERE ClassGuid=\"{4d36e978-e325-11ce-bfc1-08002be10318}\""))
|
// as per INTERFACE_PREFIXES in adafruit_board_toolkit
|
||||||
{
|
// (see https://github.com/adafruit/Adafruit_Board_Toolkit/blob/main/adafruit_board_toolkit)
|
||||||
var ports = searcher.Get().Cast<ManagementBaseObject>().ToList();
|
string[] cpb_descriptions = new string[] { "CircuitPython CDC ", "Sol CDC ", "StringCarM0Ex CDC " };
|
||||||
List<ComPort> detectedPorts = ports.Select(p =>
|
|
||||||
|
List<ComPort> detectedPorts = new List<ComPort>();
|
||||||
|
|
||||||
|
foreach (var p in new ManagementObjectSearcher("root\\CIMV2", query).Get().OfType<ManagementObject>())
|
||||||
{
|
{
|
||||||
ComPort c = new ComPort();
|
ComPort c = new ComPort();
|
||||||
|
|
||||||
|
// extract and clean up port name and number
|
||||||
c.name = p.GetPropertyValue("Name").ToString();
|
c.name = p.GetPropertyValue("Name").ToString();
|
||||||
c.vid = p.GetPropertyValue("PNPDeviceID").ToString();
|
Match mName = Regex.Match(c.name, namePattern);
|
||||||
c.description = p.GetPropertyValue("Caption").ToString();
|
if (mName.Success)
|
||||||
|
{
|
||||||
|
c.name = mName.Value;
|
||||||
|
c.num = int.Parse(c.name.Substring(3));
|
||||||
|
}
|
||||||
|
|
||||||
Match mVID = Regex.Match(c.vid, vidPattern, RegexOptions.IgnoreCase);
|
// if the port name or number cannot be determined, skip this port and move on
|
||||||
Match mPID = Regex.Match(c.vid, pidPattern, RegexOptions.IgnoreCase);
|
if (c.num < 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// get the device's VID and PID
|
||||||
|
string pidvid = p.GetPropertyValue("PNPDeviceID").ToString();
|
||||||
|
|
||||||
|
// extract and clean up device's VID
|
||||||
|
Match mVID = Regex.Match(pidvid, vidPattern, RegexOptions.IgnoreCase);
|
||||||
if (mVID.Success)
|
if (mVID.Success)
|
||||||
{
|
{
|
||||||
c.vid = mVID.Groups[1].Value;
|
c.vid = mVID.Groups[1].Value;
|
||||||
@ -688,41 +708,50 @@ namespace SimplySerial
|
|||||||
else
|
else
|
||||||
c.vid = "----";
|
c.vid = "----";
|
||||||
|
|
||||||
|
// extract and clean up device's PID
|
||||||
|
Match mPID = Regex.Match(pidvid, pidPattern, RegexOptions.IgnoreCase);
|
||||||
if (mPID.Success)
|
if (mPID.Success)
|
||||||
{
|
{
|
||||||
c.pid = mPID.Groups[1].Value;
|
c.pid = mPID.Groups[1].Value;
|
||||||
c.pid = c.pid.Substring(0, Math.Min(4, c.vid.Length));
|
c.pid = c.pid.Substring(0, Math.Min(4, c.pid.Length));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
c.pid = "----";
|
c.pid = "----";
|
||||||
|
|
||||||
Match mName = Regex.Match(c.name, namePattern);
|
// extract the device's friendly description (caption)
|
||||||
if (mName.Success)
|
c.description = p.GetPropertyValue("Caption").ToString();
|
||||||
{
|
|
||||||
c.name = mName.Value;
|
|
||||||
c.num = int.Parse(c.name.Substring(3));
|
|
||||||
if (c.num == 0)
|
|
||||||
c.name = "?";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c.name = "?";
|
|
||||||
c.num = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// attempt to match this device with a known board
|
||||||
c.board = MatchBoard(c.vid, c.pid);
|
c.board = MatchBoard(c.vid, c.pid);
|
||||||
|
|
||||||
return c;
|
// extract the device's hardware bus description
|
||||||
|
c.busDescription = "";
|
||||||
}).ToList();
|
var inParams = new object[] { new string[] { "DEVPKEY_Device_BusReportedDeviceDesc" }, null };
|
||||||
|
p.InvokeMethod("GetDeviceProperties", inParams);
|
||||||
// remove all unusable ports from the list
|
var outParams = (ManagementBaseObject[])inParams[1];
|
||||||
detectedPorts.RemoveAll(p => p.name == "?");
|
if (outParams.Length > 0)
|
||||||
|
{
|
||||||
return (detectedPorts);
|
var data = outParams[0].Properties.OfType<PropertyData>().FirstOrDefault(d => d.Name == "Data");
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
c.busDescription = data.Value.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we can determine if this is a CircuitPython board by it's bus description
|
||||||
|
foreach (string prefix in cpb_descriptions)
|
||||||
|
{
|
||||||
|
if (c.busDescription.StartsWith(prefix))
|
||||||
|
c.board.isCircuitPython = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add this port to our list of detected ports
|
||||||
|
detectedPorts.Add(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return detectedPorts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Custom structure containing information about supported CircuitPython boards
|
/// Custom structure containing information about supported CircuitPython boards
|
||||||
|
Loading…
Reference in New Issue
Block a user