Get Devpkey_Device_Busreporteddevicedesc from Win32_Pnpentity in C#

I'm trying to get the bus reported device description from a usb com port in our WPF application. Found a powershell script that gives exacly that, but as not every user has permission to run powershell, so using PowerShell.Create() is sadly not an option.

(Get-WMIObject Win32_PnPEntity | where {$_.name -match "\(com*"}).GetDeviceProperties("DEVPKEY_Device_BusReportedDeviceDesc").DeviceProperties.Data

I have tried below combinations, but I either get "Unable to cast object of type 'System.String' to type 'System.Array'" or "Invalid method Parameter(s)" on InvokeMethod.

using System;
using System.Management;

ManagementClass oClass = new ManagementClass("Win32_PnPEntity");

Object[] single = { "DEVPKEY_Device_BusReportedDeviceDesc" };
Array arr = (Array)new string[] { "DEVPKEY_Device_BusReportedDeviceDesc" };
Object[] singleArr = { single };
Object[] objsArr = { arr };
ManagementBaseObject inParams = oClass.GetMethodParameters("GetDeviceProperties");
inParams["devicePropertyKeys"] = single;
//inParams["devicePropertyKeys"] = arr;
//inParams["devicePropertyKeys"] = singleArr;
//inParams["devicePropertyKeys"] = objsArr;

oClass.InvokeMethod("GetDeviceProperties", single);
//oClass.InvokeMethod("GetDeviceProperties", singleArr);
//oClass.InvokeMethod("GetDeviceProperties", objsArr);
//oClass.InvokeMethod("GetDeviceProperties", inParams, null);

Everything takes place on the local machine.

Also found an answer from vromanov How to get Bus Reported Device Description using C# and it works, but seems like an overkill solution

1 Answer

The GetDeviceProperties method is documented like this:

Uint32 GetDeviceProperties(
  [in, optional] string                  devicePropertyKeys[],
  [out]          Win32_PnPDeviceProperty deviceProperties[]
);

So here is a sample code to call it with C#:

foreach (var mo in new ManagementObjectSearcher(null, "SELECT * FROM Win32_PnPEntity").Get().OfType<ManagementObject>())
{
    // get the name so we can do some tests on the name in this case
    var name = mo["Name"] as string;

    // add your custom test here
    if (name == null || name.IndexOf("(co", StringComparison.OrdinalIgnoreCase) < 0)
        continue;

    // call Win32_PnPEntity's 'GetDeviceProperties' method
    // prepare two arguments:
    //  1st one is an array of string (or null)
    //  2nd one will be filled on return (it's an array of ManagementBaseObject)
    var args = new object[] { new string[] { "DEVPKEY_Device_BusReportedDeviceDesc" }, null };
    mo.InvokeMethod("GetDeviceProperties", args);

    // one mbo for each device property key
    var mbos = (ManagementBaseObject[])args[1];
    if (mbos.Length > 0)
    {
        // get value of property named "Data"
        // not all objects have that so we enum all props here
        var data = mbos[0].Properties.OfType<PropertyData>().FirstOrDefault(p => p.Name == "Data");
        if (data != null)
        {
            Console.WriteLine(data.Value);
        }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

James H. Sterling

James H. Sterling

Environmental Science & Climate Journalist

James Sterling reports on renewable energy developments, climate policy, ecological conservation, and green tech innovations around the globe.

Share this article
Twitter Facebook Pinterest