简体   繁体   中英

WMI: Get list of all serial (COM) ports including virtual ports

I'm currently working on a little C# program to interact with an Arduino microcontroller. The program has a combobox where you can choose the COM-port. The µc is connected by USB and a virtual COM-port (CH340).

I use the code below to fill in the avaible COM-ports to the combobox.

private void Form1_Load(object sender, EventArgs e)
    {
        string[] PortNames = SerialPort. GetPortNames();
        comboBoxPort.Items.AddRange(PortNames);
    }

The downside of this is, you have to take a look into the Device Manager to see which one is the correct one for the µc. My PC for example has 4 active COM-ports, one physical, 2 virtual and another virtual one for the µc. What I'm searching for is a way to display the complete Name of the device with the associated COM-port (like you can find it in the Device Manager)

COM-ports in the Device Manager

After a bit of research I found out that there is another possibility by using the WMI. After a lot of testing with the "WMI Code Creator" I don't know what else I can try to accomplish what I've attended to do. All the namespaces and classes I've tried are only generating the COM-port like COM1, COM2… or they generate the hardware-id which is not useful for the user of the program. The code below is more or less exactly what I'm searching for but it only works for “real” build in COM-ports.

using System;
using System.Management;
using System.Windows.Forms;

namespace WMISample
    {
        public class MyWMIQuery
        {
            public static void Main()
            {
                try
                {
                    ManagementObjectSearcher searcher =
                        new ManagementObjectSearcher("root\\CIMV2",
                        "SELECT * FROM Win32_SerialPort");

                    foreach (ManagementObject queryObj in searcher.Get())
                    {
                        Console.WriteLine("-----------------------------------");
                        Console.WriteLine("Win32_SerialPort instance");
                        Console.WriteLine("-----------------------------------");
                        Console.WriteLine("Name: {0}", queryObj["Name"]);
                    }
                }
                catch (ManagementException e)
                {
                    MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
                }
            }
        }
    }

Is there any other possible way to get a list of all the COM-ports like there is one insinde of the Device Manager? Is it maybe possible to use the hardware-id of the devices to identify them somehow and then, in a second step get the correct name for them?

I would be very pleased if I could get some help with this. There must be a way to do this but I can't find it.

And sry for my english if something sounds wierd :)

As mentiont before here is the complete working code to fill a combobox with all avaible COM-ports and set the associated port after seletion.

(The original answer how to get the port names --> link )

Thanks @o_O for the link and I hope someone will find this code useful.

private void Form1_Load(object sender, EventArgs e)
{
    // Get all serial (COM)-ports you can see in the devicemanager
    ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\cimv2",
        "SELECT * FROM Win32_PnPEntity WHERE ClassGuid=\"{4d36e978-e325-11ce-bfc1-08002be10318}\"");

    // Sort the items in the combobox 
    CmdBoxPort.Sorted = true;

    // Add all available (COM)-ports to the combobox
    foreach (ManagementObject queryObj in searcher.Get())
        CmdBoxPort.Items.Add(queryObj["Caption"]);
}

private void CmdBoxPort_SelectedIndexChanged(object sender, EventArgs e)
{
    // Set the right port for the selected item.
    // The portname is based on the "COMx" part of the string (SelectedItem)
    string item = CmdBoxPort.SelectedItem.ToString();

    // Search for the expression "(COM" in the "selectedItem" string
    if (item.Contains("(COM"))
    {
        // Get the index number where "(COM" starts in the string
        int indexOfCom = item.IndexOf("(COM");

        // Set PortName to COMx based on the expression in the "selectedItem" string
        // It automatically gets the correct length of the COMx expression to make sure 
        // that also a COM10, COM11 and so on is working properly.
        serialPort1.PortName = item.Substring(indexOfCom + 1, item.Length - indexOfCom - 2);
    }
    else
        return;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM