Retrieve Serial Port information with Microsoft.Management.Infrastructure

535 Views Asked by At

In order to get information about Serial Port devices, with System.Management, we can do as described in Getting Serial Port Information:

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();
        }
    }
}

How can this be achieved using Microsoft.Management.Infrastructure, I haven't managed to find examples and the documentation isn't detailed enough.

1

There are 1 best solutions below

0
On

It's quite similar:

As a note, you're skipping the ConnectionOption and EnumerationOptions in your WMI Query, which is not really good PERF-wise.

Your query can then be translated to:

using Microsoft.Management.Infrastructure;
using Microsoft.Management.Infrastructure.Options;

using (var session = CimSession.Create(null) { 
    var ports = session.QueryInstances(@"root\cimv2", "WQL", "SELECT * FROM WIN32_SerialPort");
    string[] portnames = SerialPort.GetPortNames();

    var tList = (from n in portnames
                join p in ports on n equals p.CimInstanceProperties["DeviceID"].Value
                select n + " - " + p.CimInstanceProperties["Caption"].Value);
}

I'm not sure why you use string[] portnames = SerialPort.GetPortNames(); here.
You can just use the CimProperties:

using (var session = CimSession.Create(null)) {
    var ports = session.QueryInstances(@"root\cimv2", "WQL", "SELECT * FROM WIN32_SerialPort");

    var portsDescriptions = ports.Select(p =>
        $"{p.CimInstanceProperties["DeviceID"].Value} - {p.CimInstanceProperties["Caption"].Value}");

    // If you actually need to materialize a List<T>...
    portsDescriptions.ToList().ForEach(Console.WriteLine);
}

Unrelated, but could be useful: I suggest to build some methods to create a CimSession with more options. For example:

public static CimSession CreateSession(string computerName) 
    => CreateSession(computerName, string.Empty, string.Empty, null);

public static CimSession CreateSession(string computerName, string domain, string userName, SecureString password)
{
    if (string.IsNullOrEmpty(computerName) || 
        computerName.Equals("localhost", StringComparison.InvariantCultureIgnoreCase)) {
        computerName = null;
    }
    var option = new CimSessionOptions();
    if (password != null && password.Length > 0) {
        option.AddDestinationCredentials(
            new CimCredential(PasswordAuthenticationMechanism.Default, domain, userName, password));
    }
    return CimSession.Create(computerName, option);
}

So, instead of:

var session = CimSession.Create(null);

You can call it as:

// LocalHost, default permissions
var session = CreateSession(null); 

Or pass domain, Username and Password (as Char*), if needed.