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:
Figure 1 – Our 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.
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 🙂
Figure 3 – Hard 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.
Figure 4 – Hard 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.
Figure 5 – Hard 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 🙂
Figure 6 – Hard 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!