1

I'm trying to link drives to their partitions; the code is working and the data is being retrieved as a single object.

"DeviceID_0": "\\.\PPHYSICALDRIVE0",
"SerialNumber_0": "52dT9SPRq9gCRv",
"Drive_letter0_0": "G:",
"Prtition_0_0": "Disk #0, Partition #0",
"Drive_letter0_1": "H:",
"Prtition_0_1": "Disk #0, Partition #1",
"DeviceID_1": "\\.\PHYSICALDRIVE`2`",
"SerialNumber_1": "bdUxR74dG3sZuL7Cw",
"Drive_letter1_0": "M:",
"Prtition_1_0": "Disk #1, Partition #0"

I'm curious if there's a way to get a more attractive structure like this?

[
    {
        device_id: "\\\\.\\PHYSICALDRIVE0",
        serial_number: "52dT9SPRq9gCRv",
        partitions: [
            {
                letter: "G:",
                partition: "Disk #0, Partition #0"
            },
            {
                letter: "H:",
                partition: "Disk #0, Partition #1"
            }
        ]
    },
    {
        device_id: "\\\\.\\PHYSICALDRIVE1",
        serial_number: "bdUxR74dG3sZuL7Cw",
        partitions: [
            {
                letter: "M:",
                partition: "Disk #1, Partition #0"
            }
        ]
    }
]

Method in C# I am using.

public static Dictionary<string, string> LogicalDrives()
{
    Dictionary<string, string> Drive = new Dictionary<string, string>();
    using (ManagementObjectSearcher search = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive"))
    {
        int i = 0;
        foreach (ManagementObject drive in search.Get())
        {
            Drive.Add("DeviceID_" + i, drive["DeviceID"].ToString());
            Drive.Add("SerialNumber_" + i, drive["SerialNumber"].ToString());

            string antecedent = drive["DeviceID"].ToString();
            antecedent = antecedent.Replace(@"\", "\\"); 
            string query = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + antecedent + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition";
            using (ManagementObjectSearcher partitionSearch = new ManagementObjectSearcher(query))
            {
                int j = 0;
                foreach (ManagementObject part in partitionSearch.Get())
                {
                    query = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + part["DeviceID"] + "'} WHERE AssocClass = Win32_LogicalDiskToPartition";
                    using (ManagementObjectSearcher logicalpartitionsearch = new ManagementObjectSearcher(query))
                    {
                        foreach (ManagementObject logicalpartition in logicalpartitionsearch.Get())
                        {
                            Drive.Add("Drive_letter" + i + "_" + j, logicalpartition["DeviceID"].ToString());
                            Drive.Add("Prtition_" + i + "_" + j, part["DeviceID"].ToString());
                        }
                    }
                    j++;
                }
            }
            i++;
        }
    }
    return Drive;
}

I'm asking because I tried using string[][][], string[][], string[,], Also like this Dictionary<string, object> Drive = new Dictionary<string, object>(); and Dictionary<string, Dictionary<string, object>> Drive = new Dictionary<string, Dictionary<string, object>>(); but unfortunately had no luck or I'm just missing some piece.

###########[ After help from accepted answer ]

We set new Classes to collect data like so.

public class Device
{
    public string DeviceId { get; set; }
    public string SerialNumber { get; set; }
    public List<Partition> Partitions { get; set; }
        = new List<Partition>();
}


public class Partition
{
    public string Letter { get; set; }
    public string PartitionName { get; set; }
}

And also here is updated method:

public static List<Device> LogicalDrives()
{
    var results = new List<Device>();

    using (ManagementObjectSearcher search = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive"))
    {
        foreach (ManagementObject drive in search.Get())
        {
            /////////////////////
            //This was updated
            var device = new Device();
            device.DeviceId = drive["DeviceID"].ToString();
            device.SerialNumber = drive["SerialNumber"].ToString();
            results.Add(device);
            //This was updated
            /////////////////////

            string antecedent = drive["DeviceID"].ToString();
            antecedent = antecedent.Replace(@"\", "\\"); 
            string query = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + antecedent + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition";
            using (ManagementObjectSearcher partitionSearch = new ManagementObjectSearcher(query))
            {
                foreach (ManagementObject part in partitionSearch.Get())
                {
                    query = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + part["DeviceID"] + "'} WHERE AssocClass = Win32_LogicalDiskToPartition";
                    using (ManagementObjectSearcher logicalpartitionsearch = new ManagementObjectSearcher(query))
                    {
                        foreach (ManagementObject logicalpartition in logicalpartitionsearch.Get())
                        {
                            /////////////////////
                            //This was updated
                            var partition = new Partition();
                            partition.Letter = logicalpartition["DeviceID"].ToString();
                            partition.PartitionName = part["DeviceID"].ToString();
                            device.Partitions.Add(partition);
                            //This was updated
                            /////////////////////
                        }
                    }
                }
            }
        }
    }
    var resultStr = JsonConvert.SerializeObject(results, Formatting.Indented);
    Console.WriteLine(resultStr);

    return results;
}

Real results output from the method:

[
  {
    "DeviceId": "\\\\.\\PHYSICALDRIVE3",
    "SerialNumber": "240881765286406",
    "Partitions": [
      {
        "Letter": "G:",
        "PartitionName": "Disk #3, Partition #0"
      },
      {
        "Letter": "H:",
        "PartitionName": "Disk #3, Partition #1"
      }
    ]
  },
  {
    "DeviceId": "\\\\.\\PHYSICALDRIVE2",
    "SerialNumber": "6479_A749_C020_0781.",
    "Partitions": [
      {
        "Letter": "D:",
        "PartitionName": "Disk #2, Partition #0"
      }
    ]
  },
  {
    "DeviceId": "\\\\.\\PHYSICALDRIVE1",
    "SerialNumber": "E823_8FA6_BF53_0001_001B_448B_48A1_E1DB.",
    "Partitions": [
      {
        "Letter": "C:",
        "PartitionName": "Disk #1, Partition #1"
      }
    ]
  },
  {
    "DeviceId": "\\\\.\\PHYSICALDRIVE0",
    "SerialNumber": "           Z6EPB01AS",
    "Partitions": [
      {
        "Letter": "F:",
        "PartitionName": "Disk #0, Partition #0"
      }
    ]
  }
]
1
  • Use json2csharp.com to create classes for your json and then try to create objects of them in your code. Commented Feb 25, 2022 at 23:17

1 Answer 1

4

Create some models to make it easier

public class Device
{
    public string DeviceId { get; set; }
    public string SerialNumber { get; set; }
    public List<Partition> Partitions { get; set; }
        = new List<Partition>();
}


public class Partition
{
    public string Letter { get; set; }
    public string PartitionName { get; set; }
}

And now just add all Devices.

var results = new List<Device>();
...

Edit:
For Partitions

var device = new Device();
results.Add(device);

// foreach partition 
var partition = new Partition();
partition.Letter = "...";
partition.PartitionName = "...";

device.Partitions.Add(partition);

To print the results you can do

var resultStr = JsonConvert.SerializeObject(results, Formatting.Indented); 
Console.WriteLine(resultStr); 
Sign up to request clarification or add additional context in comments.

8 Comments

Thank you so much for your answer. Can you also show me how to set partitions? I managed to set result.DeviceId and result.SerialNumber but got confused on result.partitions.letter and result.partitions.partition.
Thank you for update. Is it ok to use Device result = new Device(); instead of var result = new List<Device>(); cause otherwise it gives me error CS1061
@Tiffany if result is just one device in your case and you add it to the "Drive" Dictionary then that is fine. I don't know how your current code looks.
This is the first time I've used the type of coding you demonstrated. So I'm trying to understand how it works. Sorry if I have frustrated you. I even don't know how to access it to Console.WriteLine data.
@Tiffany if you want a string representation try : var resultStr = JsonConvert.SerializeObject(result, Formatting.Indented); Console.WriteLine(resultStr);
|

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.