Getting Serial Port Information

I tried so many solutions on here that didn't work for me, only displaying some of the ports. But the following displayed All of them and their information.

        using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE Caption like '%(COM%'"))
        {
            var portnames = SerialPort.GetPortNames();
            var ports = searcher.Get().Cast<ManagementBaseObject>().ToList().Select(p => p["Caption"].ToString());

            var portList = portnames.Select(n => n + " - " + ports.FirstOrDefault(s => s.Contains(n))).ToList();

            foreach(string s in portList)
            {
                Console.WriteLine(s);
            }
        }
    }

There is a post about this same issue on MSDN:

Getting more information about a serial port in C#

Hi Ravenb,

We can't get the information through the SerialPort type. I don't know why you need this info in your application. However, there's a solved thread with the same question as you. You can check out the code there, and see if it can help you.

If you have any further problem, please feel free to let me know.

Best regards, Bruce Zhou

The link in that post goes to this one:

How to get more info about port using System.IO.Ports.SerialPort

You can probably get this info from a WMI query. Check out this tool to help you find the right code. Why would you care though? This is just a detail for a USB emulator, normal serial ports won't have this. A serial port is simply know by "COMx", nothing more.


EDIT: Sorry, I zipped past your question too quick. I realize now that you're looking for a list with the port name + port description. I've updated the code accordingly...

Using System.Management, you can query for all the ports, and all the information for each port (just like Device Manager...)

Sample code (make sure to add reference to System.Management):

using System;
using System.Management;
using System.Collections.Generic;
using System.Linq;
using System.IO.Ports;        

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var searcher = new ManagementObjectSearcher
                ("SELECT * FROM WIN32_SerialPort"))
            {
                string[] portnames = SerialPort.GetPortNames();
                var ports = searcher.Get().Cast<ManagementBaseObject>().ToList();
                var tList = (from n in portnames
                            join p in ports on n equals p["DeviceID"].ToString()
                            select n + " - " + p["Caption"]).ToList();

                tList.ForEach(Console.WriteLine);
            }

            // pause program execution to review results...
            Console.WriteLine("Press enter to exit");
            Console.ReadLine();
        }
    }
}

More info here: http://msdn.microsoft.com/en-us/library/aa394582%28VS.85%29.aspx


Use following code snippet

It gives following output when executed.

serial port : Communications Port (COM1)
serial port : Communications Port (COM2)

Don't forget to add

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

Also add reference to system.Management (by default it is not available)

C#

private void GetSerialPort()
{

    try
    {
        ManagementObjectSearcher searcher = 
            new ManagementObjectSearcher("root\\CIMV2", 
            "SELECT * FROM Win32_PnPEntity"); 

        foreach (ManagementObject queryObj in searcher.Get())
        {
            if (queryObj["Caption"].ToString().Contains("(COM"))
            {
                Console.WriteLine("serial port : {0}", queryObj["Caption"]);
            }

        }
    }
    catch (ManagementException e)
    {
        MessageBox.Show( e.Message);
    }

}

VB

  Private Sub GetAllSerialPortsName()
        Try
            Dim searcher As New ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_PnPEntity")
            For Each queryObj As ManagementObject In searcher.Get()
                If InStr(queryObj("Caption"), "(COM") > 0 Then
                    Console.WriteLine("serial port : {0}", queryObj("Caption"))
                End If
            Next
        Catch err As ManagementException
            MsgBox(err.Message)
        End Try
    End Sub

Update: You may also check for

if (queryObj["Caption"].ToString().StartsWith("serial port"))

instead of

if (queryObj["Caption"].ToString().Contains("(COM"))