Home > front end >  C# WMI MSFT_Disk syntax
C# WMI MSFT_Disk syntax

Time:09-22

This form of ManagementObject (using ".DeviceID=") assignment works:

        // get number of logical drives on given physical disk
        int n = 0;
        var id = "\\\\.\\PHYSICALDRIVE0";
        var disk = new ManagementObject("Win32_DiskDrive.DeviceID="   "'"   id   "'");
        foreach (ManagementObject dp in disk.GetRelated("Win32_DiskPartition"))
        {
            foreach (ManagementObject ld in dp.GetRelated("Win32_LogicalDisk"))   n;
        }

This form of ManagementObject (using ".Number=") assignment fails:

        // get number of logical drives on given physical disk
        int n = 0;
        var id = "0";
        ManagementObject disk = new ManagementObject("root\\Microsoft\\Windows\\Storage:MSFT_Disk.Number="   "'"   id   "'");
        foreach (ManagementObject dp in disk.GetRelated("MSFT_Partition"))
        {
            foreach (ManagementObject ld in dp.GetRelated("MSFT_Volume"))   n;
        }

The exception is "Invalid object path". I have spent an embarrassing amount of time trying to figure out what I am doing wrong...and have no clue.

The specific item being searched for here is not the relevant issue. The proper syntax of using the two statements is what I am trying to understand...

The path for the working case is: "root\CIMV2" and the path to the failing case is: "root\Microsoft\Windows\Storage".

The failing statement is: "foreach (ManagementObject dp in disk.GetRelated("MSFT_Partition"))"

CodePudding user response:

There are a number of ways to retrieve the information. Try the following instead:

private int GetNumberOfLogicalDrives(int number)
{
    int numLogicalDrives = 0;
    using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(new ManagementScope(@"root\Microsoft\Windows\Storage"), new SelectQuery($"SELECT * FROM MSFT_Disk WHERE Number = {number}")))
    {
        using (ManagementObjectCollection logicalDrives = searcher.Get())
        {
            if (logicalDrives != null && logicalDrives.Count > 0)
            {
                foreach (ManagementObject mObj in logicalDrives)
                {
                    //re-initialize
                    numLogicalDrives = 0;

                    if (mObj == null)
                        continue;

                    foreach (ManagementObject mObjDP in mObj.GetRelated("MSFT_Partition"))
                    {
                        if (mObjDP == null)
                            continue;

                        foreach (ManagementObject mObjLD in mObjDP.GetRelated("MSFT_Volume"))
                        {
                            if (mObjLD == null)
                                continue;

                            //skip if there isn't a drive letter
                            if (String.IsNullOrEmpty(mObjLD["DriveLetter"]?.ToString().Trim()))
                                continue;

                            numLogicalDrives  ; //increment
                        }
                    }

                    Debug.WriteLine($"number: {number}; numLogicalDrives: {numLogicalDrives}");
                }
            }
        }
    }

    return numLogicalDrives;
}

Usage:

int numLogicalDrives = GetNumberOfLogicalDrives(0);

Resources:

CodePudding user response:

@user9938: I appreciate your reply and the focus on the "MSFT_xxx" items. I was looking for an analogous syntax solution to the "Win32_xxx" approach.

After considerable trial & error, It appears that the approach of assigning the specific disk directly in the ManagementObject declaration statement is simply not supported when using "MSFT_Disk".

Either of these two statements work correctly:

var disk = new ManagementObject("Win32_DiskDrive=

var disk = new ManagementObject("Win32_DiskDrive.DeviceID=

There does not appear to be any analogous statement when using "MSFT_Disk".

Thus, the simplest code solution is:

        var phy = "0";    // ... or any valid disk index
        int num = 0;
        var disk = new ManagementObject("Win32_DiskDrive='\\\\.\\PHYSICALDRIVE"   phy   "'");
        foreach (ManagementObject dp in disk.GetRelated("Win32_DiskPartition"))
        {
            foreach (ManagementObject ld in dp.GetRelated("Win32_LogicalDisk"))   num;
        }
  • Related