none
WMI Win32_DiskDrive, Win32_LogicalDisk & Win32_DiskPartition

    Question

  • Hi,

    I am trying to get the partition letter and label of a drive, as well as the size of the partition and free space. I also want to get the amount of physical disks and the total size of each of them with their health status.

    What I have done is, with Win32_LogicalDisk I have all the partition info I want.The trouble I'm having is matching it up to a physical disk and getting the health status of that disk.

    I've currently got it split into two sections.

    Section 1: (Partition Info)

     

    public static string[,] getSection1(ManagementScope scope)
      {
        ObjectQuery query =
            new ObjectQuery("SELECT * FROM Win32_LogicalDisk WHERE DriveType=3"); // Create query to select all the hdd's
    
        ManagementObjectSearcher searcher =
          new ManagementObjectSearcher(scope, query); // run the query
    
        ManagementObjectCollection queryCollection = searcher.Get(); // get the results
        string sVolumeLabel = "";
        string[,] saReturn = new string[queryCollection.Count, 7];
        int i = 0; // counter for foreach
    
        foreach (ManagementObject m in queryCollection)
        {
          if (string.IsNullOrEmpty(Convert.ToString(m["VolumeName"]))) { sVolumeLabel = "Local Disk"; } else { sVolumeLabel = Convert.ToString(m["VolumeName"]); } // Disk Label
          string sSystemName = Convert.ToString(m["SystemName"]); // Name of computer
          string sDriveLetter = Convert.ToString(m["Name"]); // Drive Letter
    
          decimal dSize = Math.Round((Convert.ToDecimal(m["Size"]) / 1073741824), 2); //HDD Size in Gb
          decimal dFree = Math.Round((Convert.ToDecimal(m["FreeSpace"]) / 1073741824), 2); // Free Space in Gb
          decimal dUsed = dSize - dFree; // Used HDD Space in Gb
          
          int iPercent = Convert.ToInt32((dFree / dSize) * 100); // Percentage of free space
                
          saReturn[i,0] = sSystemName;
          saReturn[i,1] = sDriveLetter;
          saReturn[i,2] = sVolumeLabel;
          saReturn[i,3] = Convert.ToString(dSize);
          saReturn[i,4] = Convert.ToString(dUsed);
          saReturn[i,5] = Convert.ToString(dFree);
          saReturn[i,6] = Convert.ToString(iPercent);
    
          i++; // increase counter. This will add the above details for the next drive.
        }
    
        return (saReturn);
      }
    

     

    and Section 2: (Disk Info)

     

    public static void getSection2(ManagementScope scope) //string[,]
      {
        ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Diskdrive"); // Create query to select all the hdd's
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query); // run the query
        ManagementObjectCollection queryCollection = searcher.Get(); // get the results
    
        foreach (ManagementObject m in queryCollection)
          {
            Console.WriteLine(Math.Round((Convert.ToDecimal(m["Size"]) / 1073741824), 2));
            foreach (ManagementObject b in m.GetRelated("Win32_DiskPartition"))
            {
              //Console.WriteLine("{0}", b["Name"]);
              foreach (ManagementBaseObject c in b.GetRelated("Win32_LogicalDisk"))
              {
                if (Convert.ToInt32(c["DriveType"]) == 3)
                {
                  Console.WriteLine("\t System: {0}", m["SystemName"]);
                  //Console.WriteLine(); // Disk Count
                  Console.WriteLine("\t Size: {0}", Math.Round((Convert.ToDecimal(m["Size"]) / 1073741824), 2));
                  Console.WriteLine("\t Health: {0}", Convert.ToString(m["Status"]));
                }
              }
            }
          }
        }
    

     

     

    Where I was after help is with section 2.

    I wasn't sure how to get just the local disks inside the machine. I thought I could put a counter in, but that wouldn't be reliable.

    All help is muchly appreciated :)

    Sunday, March 27, 2011 4:56 AM

Answers

  • How about InterfaceType property of Win32_Diskdrive class? get the value of this property. If the value is "IDE" or "SATA" then disk is inside your machine. If it is "USB" or other then it's external disk. 


    Please mark this post as answer if it solved your problem. Happy Programming !!!
    • Marked as answer by Rob1983 Saturday, April 02, 2011 1:49 AM
    Sunday, March 27, 2011 7:18 AM
  • Hi Rob1983,

    If you want to use the WMI to achieve that , I think the following link can help you much.
    http://www.codeproject.com/KB/system/WMISysInfo.aspx

    Also, there is a link with the demo which is implemented by Aliriza.Shirazi.
    http://www.codeproject.com/KB/system/GetHardwareInformation.aspx

    I have download the demo to check. It works well. When you run the the GetHardwareInfo.exe program, then click the "Data Storage" item, then choose the "Win32_DiskPartion", then it will show all detaied information of each disk in your computer. You can download the sourcecode form the link too. Thanks.


    Vin Jin [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Rob1983 Friday, April 01, 2011 11:09 PM
    • Unmarked as answer by Rob1983 Saturday, April 02, 2011 12:13 AM
    • Marked as answer by Rob1983 Saturday, April 02, 2011 12:15 AM
    Wednesday, March 30, 2011 9:25 AM

All replies

  • How about InterfaceType property of Win32_Diskdrive class? get the value of this property. If the value is "IDE" or "SATA" then disk is inside your machine. If it is "USB" or other then it's external disk. 


    Please mark this post as answer if it solved your problem. Happy Programming !!!
    • Marked as answer by Rob1983 Saturday, April 02, 2011 1:49 AM
    Sunday, March 27, 2011 7:18 AM
  • I looked at that, and think it may be the way to go. Though it doesn't have a value of SATA, just IDE. I also need to check for SCSI as well, but not sure if SCSI is internal only.
    Sunday, March 27, 2011 9:38 AM
  • Hi Bob1983,

    Base on your description, do you mean you want to get the information of each disk? If so, I think  you can handle the "GetDiskFreeSpace" method.

    Here is the link about how to invoke it in C#: http://www.pinvoke.net/default.aspx/kernel32/GetDiskFreeSpace.html

    And here is the sample for you: 

     [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern bool GetDiskFreeSpace(string lpRootPathName,
          out uint lpSectorsPerCluster,
          out uint lpBytesPerSector,
          out uint lpNumberOfFreeClusters,
          out uint lpTotalNumberOfClusters);
    
        private void Test(String path)
        {
          uint SectorsPerCluster;
          uint BytesPerSector;
          uint NumberOfFreeClusters;
          uint TotalNumberOfClusters;
    
          GetDiskFreeSpace(path, out SectorsPerCluster, out BytesPerSector, out NumberOfFreeClusters, out TotalNumberOfClusters);
    
          Console.WriteLine("Sectors Per Cluster: {0}", SectorsPerCluster);
          Console.WriteLine("Bytes Per Sector: {0}", BytesPerSector);
          Console.WriteLine("Number Of Free Clusters: {0}", NumberOfFreeClusters);
          Console.WriteLine("Total Number Of Clusters: {0}", TotalNumberOfClusters);
    
          long Bytes = (long)NumberOfFreeClusters * SectorsPerCluster * BytesPerSector;
          long TotalBytes = (long)TotalNumberOfClusters * SectorsPerCluster * BytesPerSector;
    
          decimal GigaBytes = (decimal)(Bytes / 1024 / 1024 / 1024);
          Console.WriteLine("Total Free Space in giga bytes: {0}", GigaBytes);
    
          decimal GigaTotalBytes = (decimal)(TotalBytes / 1024 / 1024 / 1024);
          Console.WriteLine("Total Free Space in giga bytes: {0}", GigaTotalBytes);
    
          ManagementScope scope = new ManagementScope(@"\\VincentKing\root\cimv2");
          scope.Connect();
          ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
          ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
        }

    The test method need a string parameter. You can pass it by the path of the disk, such as "C:\\" or "D:\\". I have test it as "Test(@"C:\\");". It can work for me. If any misunderstanding, please feel free let me know. Thanks.


    Vin Jin [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, March 29, 2011 9:09 AM
  • Sorry for the delay in my reply.

    Vin Jin, That looks like it could come in handy. I was using WMI because I need to connect to multiple servers and get the details of their hdss etc as well.

    I'll have a look at what you've posted and let you know ho I go with it :)

    Wednesday, March 30, 2011 2:06 AM
  • Hi Rob1983,

    If you want to use the WMI to achieve that , I think the following link can help you much.
    http://www.codeproject.com/KB/system/WMISysInfo.aspx

    Also, there is a link with the demo which is implemented by Aliriza.Shirazi.
    http://www.codeproject.com/KB/system/GetHardwareInformation.aspx

    I have download the demo to check. It works well. When you run the the GetHardwareInfo.exe program, then click the "Data Storage" item, then choose the "Win32_DiskPartion", then it will show all detaied information of each disk in your computer. You can download the sourcecode form the link too. Thanks.


    Vin Jin [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Rob1983 Friday, April 01, 2011 11:09 PM
    • Unmarked as answer by Rob1983 Saturday, April 02, 2011 12:13 AM
    • Marked as answer by Rob1983 Saturday, April 02, 2011 12:15 AM
    Wednesday, March 30, 2011 9:25 AM
  • Thank you Vin Jin.
    I have just started reading the first link and it looks like it will get me through  :)
    Thank you very much for your help, must admit, I'm a little embarrassed I didn't find that page when I was searching hehe

    After going through all of that page and going from vb to c# I ended up using Adavesh's suggestion.
    Alos fixed up my code to only run through the WMI stuff once, creating a 3D array with all the info I need.

    Thank you very much to both of you. Adavesh for providing the solution and Vin Jin for providing the link to the info that helped me to better optimise my code :)
    Friday, April 01, 2011 11:11 PM