1

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.

Jimi
  • 29,621
  • 8
  • 43
  • 61

1 Answers1

0

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.

Jimi
  • 29,621
  • 8
  • 43
  • 61