HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Find a serial port device through WMI (windows management instrumentation)

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
finddeviceinstrumentationserialwmimanagementportthroughwindows

Problem

The idea here is to be able to find a USB serial port device connected during runtime, thus not knowing its port number, and use it in the application to retrieve information from the device.

string comportInfo = string.Empty;

using (var entitySearcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PnPEntity WHERE Caption LIKE '%" + SerialPortToFind + "%'"))
{
    using (var serialPortSearcher = new ManagementObjectSearcher("root\\WMI", "SELECT * FROM MSSerial_PortName"))
    {
        //testBase.SamplerWithCancel is like a for loop with exception control, a time between interations and amount of iterations to be made. It expects a true or false value to determine whether a desired condition is met. Failing to return a true value in the specified iterations throws an exception.
        testBase.SamplerWithCancel(() =>
            {
            var portList = serialPortSearcher.Get().Cast().ToList();
            var matchingEntities = entitySearcher.Get().Cast().First();

            if (portList.Count != 0 && matchingEntities != null)
            {
                foreach (ManagementBaseObject port in portList)
                {
                    if (port["InstanceName"].ToString().Contains(matchingEntities["DeviceID"].ToString()))
                    {
                        comportInfo = port["PortName"].ToString();
                    }
                }
                return true;
            }
            else
                return false;
        }, "Serial port not found", 3, 1500, 500, false, false);
    }
}


The code works well, but I want to know where I can improve it to make it more resilient and less error prone.

I feel like using LINQ would be way more appropiate than what I did.

Solution

The code works well, but I want to know where I can improve it to make it more resilient and less error prone.

-
A very good start would be to always use braces {} although they might be optional.

-
By stacking the using blocks you can save some horizontal spacing.

-
By reverting the condition of if (portList.Count != 0 && matchingEntities != null) you could return early and the else would be (like now) redundant and could be removed which will save some spacing too.

-
The naming of the variables could need some imporvements too, e.g the plural matchingEntities doesn't match the result of the call to First().

-
Storing the result of matchingEntities["DeviceID"].ToString() into a variable will speed up things.

Implementing the mentioned points will lead to

string comportInfo = string.Empty;

using (var entitySearcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PnPEntity WHERE Caption LIKE '%" + SerialPortToFind + "%'"))    
using (var serialPortSearcher = new ManagementObjectSearcher("root\\WMI", "SELECT * FROM MSSerial_PortName"))
{
    //testBase.SamplerWithCancel is like a for loop with exception control, a time between interations and amount of iterations to be made. It expects a true or false value to determine whether a desired condition is met. Failing to return a true value in the specified iterations throws an exception.
    testBase.SamplerWithCancel(() =>
        {
        var portList = serialPortSearcher.Get().Cast().ToList();
        var matchingEntity = entitySearcher.Get().Cast().First();

        if (portList.Count == 0 || matchingEntity == null)
        {
            return false;
        }

        string entity = matchingEntity["DeviceID"].ToString();

        foreach (ManagementBaseObject port in portList)
        {
            if (port["InstanceName"].ToString().Contains(entity))
            {
                comportInfo = port["PortName"].ToString();
            }
        }

        return true;

    }, "Serial port not found", 3, 1500, 500, false, false);
}

Code Snippets

string comportInfo = string.Empty;

using (var entitySearcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PnPEntity WHERE Caption LIKE '%" + SerialPortToFind + "%'"))    
using (var serialPortSearcher = new ManagementObjectSearcher("root\\WMI", "SELECT * FROM MSSerial_PortName"))
{
    //testBase.SamplerWithCancel is like a for loop with exception control, a time between interations and amount of iterations to be made. It expects a true or false value to determine whether a desired condition is met. Failing to return a true value in the specified iterations throws an exception.
    testBase.SamplerWithCancel(() =>
        {
        var portList = serialPortSearcher.Get().Cast<ManagementBaseObject>().ToList();
        var matchingEntity = entitySearcher.Get().Cast<ManagementBaseObject>().First();

        if (portList.Count == 0 || matchingEntity == null)
        {
            return false;
        }

        string entity = matchingEntity["DeviceID"].ToString();

        foreach (ManagementBaseObject port in portList)
        {
            if (port["InstanceName"].ToString().Contains(entity))
            {
                comportInfo = port["PortName"].ToString();
            }
        }

        return true;

    }, "Serial port not found", 3, 1500, 500, false, false);
}

Context

StackExchange Code Review Q#111178, answer score: 3

Revisions (0)

No revisions yet.