Home > Enterprise >  C# Dictionary to Array of objects
C# Dictionary to Array of objects

Time:02-26

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"
      }
    ]
  }
]

CodePudding user response:

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); 
  • Related