Getting Hard Disk Information with WMI and Visual Studio 2012

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Introduction

Hello again! Today I will talk about how to retrieve hard disk information via WMI. Sometimes it is necessary to know how much free space is available on your disk, what type of drive it is, and/or what file system is being used. Not quite so often, we might need to know what the hard disk’s serial number is; especially when we want to let users buy licenses for our programs. I will cover all of these with VB and C#. Let’s get the party started!

WMI

WMI (Windows Management Instrumentation), as quoted from MSDN, is the infrastructure for management data and operations on Windows-based operating systems. OK, in layman’s terms this means that via the use of WMI, we can retrieve data that is at the heart of our hardware and / or services. We’ll cover the above list of topics today, especially the hard disk serial number, which is not as easy to come by usually.

How It Works

There are two ways to make use of WMI in our programs. We could write queries ( similar to SQL / LINQ queries ), known as WQL, to obtain this info, or we could make use of the System.Management and System.Management.Instrumentation namespaces, which have these queries built in. This is what we’ll use today.

Design

Open Visual Studio 2012 and choose either a VB Windows Forms Project or a C# Windows Forms Project. Give it any name of your choice and add five buttons. Your design screen should resemble Figure 1:

Our Design
Figure 1Our Design

Add the System.Management Reference to your project, by clicking Project, References, System.Management.

Namespaces

Add the following namespaces to your code:

VB.NET :

Imports System.Management
imports System.Management.Instrumentation 

C# :

using System.Management;
using System.Management.Instrumentation;

Getting the Serial Number

Add the next code segment:

VB.NET :

    Public Function GetHDSerialNo(ByVal strDrive As String) As String 'Get HD Serial Number

        'Ensure Valid Drive Letter Entered, Else, Default To C
        If strDrive = "" OrElse strDrive Is Nothing Then

            strDrive = "C"

        End If

        'Make Use Of Win32_LogicalDisk To Obtain Hard Disk Properties
        Dim moHD As New ManagementObject("Win32_LogicalDisk.DeviceID=""" + strDrive + ":""")

        'Get Info
        moHD.[Get]()

        'Get Serial Number
        Return moHD("VolumeSerialNumber").ToString()

    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        MessageBox.Show("Hard Disk Serial Number = " & GetHDSerialNo("C")) 'Call GetHDSerialNo Sub

    End Sub

C# :

    public string GetHDSerialNo(string strDrive) //Get HD Serial Number
    {
           //Ensure Valid Drive Letter Entered, Else, Default To C
	        if (string.IsNullOrEmpty(strDrive) || strDrive == null)
            {

		        strDrive = "C";

	        }

        //Make Use Of Win32_LogicalDisk To Obtain Hard Disk Properties
	    ManagementObject moHD = new ManagementObject("Win32_LogicalDisk.DeviceID=\"" + strDrive + ":\"");

	    //Get Info
	    moHD.Get();

	    //Get Serial Number
	    return moHD["VolumeSerialNumber"].ToString();

    }

        private void Button1_Click(System.Object sender, System.EventArgs e)
        {

            MessageBox.Show("Hard Disk Serial Number = " + GetHDSerialNo("C")); //Call GetHDSerialNo Sub

        }    

Here, we first check to see if a valid drive letter has been supplied, else we will default to C:\. We then make use of the Win32_LogicalDisk object to obtain the particular disk’s properties. At the end we reference the VolumeSerialNumber property, which will give us the disk’s serial number. Lastly, we called this sub from our Button.

Hard Disk Serial Number
Figure 2 Hard Disk Serial Number

Get Hard Disk Size

Add the next code.

VB.NET :

    Public Function GetHDSize(ByVal strDrive As String) As Double 'Get Size of Specified Disk

        'Ensure Valid Drive Letter Entered, Else, Default To C
        If strDrive = "" OrElse strDrive Is Nothing Then

            strDrive = "C"

        End If

        'Make Use Of Win32_LogicalDisk To Obtain Hard Disk Properties
        Dim moHD As New ManagementObject("Win32_LogicalDisk.DeviceID=""" + strDrive + ":""")

        'Get Info
        moHD.[Get]()

        'Get Hard Disk Size
        Return Convert.ToDouble(moHD("Size"))

    End Function

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

        Dim dblSize As Double 'Store Size

        dblSize = Math.Round(GetHDSize("C") / 1024 / 1024 / 1024) 'Call GetHDSize Sub and Divide 3 Times By 1024 ( Byte ) To Give GB

        '1 KB = 1024 - KiloByte
        '1 MB = 1024 ^ 2 - MegaByte
        '1 GB = 1024 ^ 3 - GigaByte
        '1 TB = 1024 ^ 4 - TeraByte
        '1 PB = 1024 ^ 5 - PetaByte
        '1 EB = 1024 ^ 6 - ExaByte
        '1 ZB = 1024 ^ 7 - ZettaByte
        '1 YB = 1024 ^ 8 - YottaByte
        '1 BB = 1024 ^ 9 - BrontoByte

        MessageBox.Show("Hard Disk Size = " & dblSize.ToString() & " GB") 'Display Result

    End Sub    

C# :

    public double GetHDSize(string strDrive) //Get Size of Specified Disk
    {
        //Ensure Valid Drive Letter Entered, Else, Default To C
        if (string.IsNullOrEmpty(strDrive) || strDrive == null)
        {

            strDrive = "C";

        }

        //Make Use Of Win32_LogicalDisk To Obtain Hard Disk Properties
	    ManagementObject moHD = new ManagementObject("Win32_LogicalDisk.DeviceID=\"" + strDrive + ":\"");

        //Get Info
	    moHD.Get();

        //Get Hard Disk Size
	    return Convert.ToDouble(moHD["Size"]);

    }

        private void Button2_Click(System.Object sender, System.EventArgs e)
      {
          double dblSize = 0; //Store Size

          dblSize = Math.Round(GetHDSize("C") / 1024 / 1024 / 1024); //Call GetHDSize Sub and Divide 3 Times By 1024 ( Byte ) To Give GB

	         //1 KB = 1024 - KiloByte
	         //1 MB = 1024 ^ 2 - MegaByte
	        //1 GB = 1024 ^ 3 - GigaByte
	         //1 TB = 1024 ^ 4 - TeraByte
	          //1 PB = 1024 ^ 5 - PetaByte
	        //1 EB = 1024 ^ 6 - ExaByte
	        //1 ZB = 1024 ^ 7 - ZettaByte
	        //1 YB = 1024 ^ 8 - YottaByte
	        //1 BB = 1024 ^ 9 - BrontoByte

          MessageBox.Show("Hard Disk Size = " + dblSize.ToString() + " GB"); //Display Result

        }    

The Function’s code is almost exactly the same as the GetHDSerialNo function; the only difference is that we make use of the Size parameter in our function. Just a note, all the coming Functions will operate the same way, so I won’t go into too many details again about the methodology used in these functions.

The resulting number will not be rounded off. It will also not display KB, MB, GB, or even TB. We have to incorporate that logic ourselves. Luckily, that is quite easy! All we need to do is to divide the result x amount of times with 1024 ( Byte size ). I divided it three times, and it gave me the correct result in GigaBytes.

Many people do not know the levels of these sizes, that is why I included it in here. Just to be interesting 🙂

Hard Disk Size
Figure 3Hard Disk Size

Getting Free space

Add the next code.

VB.NET :

    Public Function GetHDFreeSpace(ByVal strDrive As String) As Double

        'Ensure Valid Drive Letter Entered, Else, Default To C
        If strDrive = "" OrElse strDrive Is Nothing Then

            strDrive = "C"

        End If

        'Make Use Of Win32_LogicalDisk To Obtain Hard Disk Properties
        Dim moHD As New ManagementObject("Win32_LogicalDisk.DeviceID=""" + strDrive + ":""")

        'Get Info
        moHD.[Get]()

        'Get Hard Disk Free Space
        Return Convert.ToDouble(moHD("FreeSpace"))

    End Function

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

        Dim dblFree As Double 'Store Size

        dblFree = Math.Round(GetHDFreeSpace("C") / 1024 / 1024 / 1024) 'Call GetHDFreeSpace Sub and Divide 3 Times By 1024 ( Byte ) To Give GB

        '1 KB = 1024 - KiloByte
        '1 MB = 1024 ^ 2 - MegaByte
        '1 GB = 1024 ^ 3 - GigaByte
        '1 TB = 1024 ^ 4 - TeraByte
        '1 PB = 1024 ^ 5 - PetaByte
        '1 EB = 1024 ^ 6 - ExaByte
        '1 ZB = 1024 ^ 7 - ZettaByte
        '1 YB = 1024 ^ 8 - YottaByte
        '1 BB = 1024 ^ 9 - BrontoByte

        MessageBox.Show("Hard Disk Free Space = " & dblFree.ToString & " GB") 'Display Result

    End Sub    

C# :

    public double GetHDFreeSpace(string strDrive)
    {
        //Ensure Valid Drive Letter Entered, Else, Default To C
        if (string.IsNullOrEmpty(strDrive) || strDrive == null)
        {

            strDrive = "C";

        }

        //Make Use Of Win32_LogicalDisk To Obtain Hard Disk Properties
	    ManagementObject moHD = new ManagementObject("Win32_LogicalDisk.DeviceID=\"" + strDrive + ":\"");

        //Get Info
	    moHD.Get();

        //Get Hard Disk Free Space
	    return Convert.ToDouble(moHD["FreeSpace"]);

    }

        private void Button3_Click(System.Object sender, System.EventArgs e)
        {

            double dblFree = 0; //Store Size

            dblFree = Math.Round(GetHDFreeSpace("C") / 1024 / 1024 / 1024); //Call GetHDFreeSpace Sub and Divide 3 Times By 1024 ( Byte ) To Give GB

	        //1 KB = 1024 - KiloByte
	        //1 MB = 1024 ^ 2 - MegaByte
	        //1 GB = 1024 ^ 3 - GigaByte
	        //1 TB = 1024 ^ 4 - TeraByte
	        //1 PB = 1024 ^ 5 - PetaByte
	        //1 EB = 1024 ^ 6 - ExaByte
	        //1 ZB = 1024 ^ 7 - ZettaByte
	        //1 YB = 1024 ^ 8 - YottaByte
	        //1 BB = 1024 ^ 9 - BrontoByte

	         MessageBox.Show("Hard Disk Free Space = " + dblFree.ToString() + " GB"); //Display Result

        }    

Works precisely the same way as Size, but we make use of the FreeSpace property.

Hard Disk Free Space
Figure 4Hard Disk Free Space

Getting the Drive Type

VB.NET :

    Public Function GetHDDriveType(ByVal strDrive As String) As String

        'Ensure Valid Drive Letter Entered, Else, Default To C
        If strDrive = "" OrElse strDrive Is Nothing Then

            strDrive = "C"

        End If

        'Make Use Of Win32_LogicalDisk To Obtain Hard Disk Properties
        Dim moHD As New ManagementObject("Win32_LogicalDisk.DeviceID=""" + strDrive + ":""")

        'Get Info
        moHD.[Get]()

        'Get Drive Type
        Return moHD("DriveType").ToString()

    End Function

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click

        Dim strDriveType As String 'Determine Drive Type

        Select Case GetHDDriveType("C")

            Case "0"

                strDriveType = "Unknown"

            Case "1"

                strDriveType = "Readable"

            Case "2"

                strDriveType = "Writable"

            Case "3"

                strDriveType = "Read / Write Supported"

            Case "4"

                strDriveType = "Write Once"

        End Select

        MessageBox.Show("Hard Disk Drive Type = " & strDriveType)

    End Sub    

C# :

    public string GetHDDriveType(string strDrive)
    {
        //Ensure Valid Drive Letter Entered, Else, Default To C
        if (string.IsNullOrEmpty(strDrive) || strDrive == null)
        {

            strDrive = "C";

        }

        //Make Use Of Win32_LogicalDisk To Obtain Hard Disk Properties
	    ManagementObject moHD = new ManagementObject("Win32_LogicalDisk.DeviceID=\"" + strDrive + ":\"");

        //Get Info
	    moHD.Get();

        //Get Drive Type
	    return moHD["DriveType"].ToString();

    }

        private void Button4_Click(System.Object sender, System.EventArgs e)
        {

            string strDriveType = null; //Determine Drive Type

	        switch (GetHDDriveType("C"))
            {

		    case "0":
			    strDriveType = "Unknown";
			    break;
		    case "1":
			    strDriveType = "Readable";
			    break;
		    case "2":
			    strDriveType = "Writable";
			    break;
		    case "3":
			    strDriveType = "Read / Write Supported";
			    break;
		    case "4":
			    strDriveType = "Write Once";
                break;
	        }

	        MessageBox.Show("Hard Disk Drive Type = " + strDriveType);
        }    

The drive type property tells us if the particular disk in question is writable or not. The result will be numeric, so we have to convert that numeric value into something understandable. My hard disk returned 3 – which supports reading and writing. If we were using a CD for example, then it would have been readable only.

Hard Disk Type
Figure 5Hard Disk Type

Getting the File System

VB.NET :

    Public Function GetHDFileSystem(ByVal strDrive As String) As String

        'Ensure Valid Drive Letter Entered, Else, Default To C
        If strDrive = "" OrElse strDrive Is Nothing Then

            strDrive = "C"

        End If

        'Make Use Of Win32_LogicalDisk To Obtain Hard Disk
        Dim moHD As New ManagementObject("Win32_LogicalDisk.DeviceID=""" + strDrive + ":""")

        'Get Info
        moHD.[Get]()

        'Get File System
        Return moHD("FileSystem").ToString()

    End Function

    Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click

        MessageBox.Show("Hard Disk File System = " & GetHDFileSystem("C")) 'Call FileSystem Sub

    End Sub    

C# :

    public string GetHDFileSystem(string strDrive)
    {
        //Ensure Valid Drive Letter Entered, Else, Default To C
        if (string.IsNullOrEmpty(strDrive) || strDrive == null)
        {

            strDrive = "C";

        }

        //Make Use Of Win32_LogicalDisk To Obtain Hard Disk Properties
	    ManagementObject moHD = new ManagementObject("Win32_LogicalDisk.DeviceID=\"" + strDrive + ":\"");

        //Get Info
	    moHD.Get();

        //Get File System
	    return moHD["FileSystem"].ToString();

    }

        private void Button5_Click(System.Object sender, System.EventArgs e)
        {

	    MessageBox.Show("Hard Disk File System = " + GetHDFileSystem("C")); //Call GetHDFileSystem

        }    

No surprises there 🙂

Hard Disk File System
Figure 6Hard Disk File System

Conclusion

Obviously, this is just the tip of the iceberg. There are many more things you could achieve with WMI. The onus now rests on you to ensure that you dig deeper into the world of WMI. I am attaching both project’s, in zipped format, below in case you have missed a step or two. I hope you have enjoyed this article. Until next time, cheers!

 

Hannes DuPreez
Hannes DuPreez
Ockert J. du Preez is a passionate coder and always willing to learn. He has written hundreds of developer articles over the years detailing his programming quests and adventures. He has written the following books: Visual Studio 2019 In-Depth (BpB Publications) JavaScript for Gurus (BpB Publications) He was the Technical Editor for Professional C++, 5th Edition (Wiley) He was a Microsoft Most Valuable Professional for .NET (2008–2017).

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read