In this article I, will present a glimpse of WMI technology and how you can work with WMI using the WMI Query Language in C#. I will then discuss a scenario where you can put WMI to use in the real world.
What is WMI?
WMI is the acronym for Windows Management Instrumentation, a COM based Microsoft technology used to retrieve system related information. You can use this technology to retrieve the CPU ID, MAC ID, etc. of your system. It comprises of a collection of types that act as a wrapper around the native types to retrieve hardware related information. WMI facilitates a low-level communication with the host Operating System. You can use WMI to work with performance counters or retrieve hardware information from a system.
You can use WMI to retrieve metadata information of your system hardware like the following:
- HDD Serial Number
- HDD Sizes
- HDD Free Space
- CPU Serial Number
- CPU Clock Speed
- CPU Socket Type
- Network Adapter MAC Address
- Network Adapter Default Gateway
We have had enough of theoretical information -- let’s now dig into some code.
Programming WMI in C#
The following code snippet uses WQL query to populate a list with the names of logical disks in your system. A typical WMI query looks like this:
Select * FROM Win32_Processor
As you can see in the code snippet, the SelectQuery class is used to formulate a WQL query.
static List<string> PopulateDisk()
List<string> disk = new List<string>();
SelectQuery selectQuery = new SelectQuery("Win32_LogicalDisk");
ManagementObjectSearcher mnagementObjectSearcher = new ManagementObjectSearcher(selectQuery);
foreach (ManagementObject managementObject in mnagementObjectSearcher.Get())
Note that you should include the System.Management namespace (available as part of System.Management.dll) in your project. The WMI classes included as part of this namespace include the following:
- Win32_LogicalDisk -- this class represents a data source that corresponds to the storage device in your system. You can use this class to retrieve the serial number, available free space and initial size of HDD.
- Win32_NetworkAdapterConfiguration -- this class represents the attributes of a network adapter in your system. You can use this class to retrieve the MAC address, IP status or the default IP gateway information.
- Win32_Processor -- this class represents the processor running on a system that has windows operation system installed. You can use this class to retrieve CPU Id, CPU status, CPU clock speed, etc. of the processors in your system.
To obtain the metadata information of the fixed disks in your system, i.e., the name, freespace, disk size, etc., you can use the following code.
static void GetDiskMetadata()
System.Management.ManagementScope managementScope = new System.Management.ManagementScope();
System.Management.ObjectQuery objectQuery = new System.Management.ObjectQuery("select FreeSpace,Size,Name from Win32_LogicalDisk where DriveType=3");
ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher(managementScope,objectQuery);
ManagementObjectCollection managementObjectCollection = managementObjectSearcher.Get();
foreach (ManagementObject managementObject in managementObjectCollection)
Console.WriteLine("Disk Name : " + managementObject["Name"].ToString());
Console.WriteLine("FreeSpace: " + managementObject["FreeSpace"].ToString());
Console.WriteLine("Disk Size: " + managementObject["Size"].ToString());
The following code snippet illustrates how you can retrieve the volume serial number of the hard disks in your system.
static string GetHardDiskSerialNumber(string drive = "C")
ManagementObject managementObject = new ManagementObject("Win32_LogicalDisk.DeviceID=\"" + drive + ":\"");
To obtain the processorId of the processor in your system, you would need to specify the "ProcessorId" in the properties array of the ManagementObject class instance as shown in the code snippet that follows.
string processorId = managementObject.Properties["ProcessorId"].Value.ToString();
To obtain the clock speed of the processor in your system, you would need to specify the "CurrentClockSpeed" in the properties array of the ManagementObject class instance as shown in the code snippet that follows.
Int32 clockSpeed = Convert.ToInt32(managementObject.Properties["CurrentClockSpeed"].Value.ToString());
Now that we have explored programming WMI using C#, let me tell you a practical example where you can put WMI to use. I did actually make use of WMI in a few of my projects to implement node locking - a feature that prevents an application from copied into another system and being executed on it.
Let me explain what I did to implement node locking and why it was needed. Node locking implies locking a node -- a node is just a system. In essence, this concept prevents an executable generated by your application from being installed and executed in multiple systems. I used WMI to retrieve the hardware details of the system on which the application needs to be installed and executed. Next, these details were encrypted using an encryption algorithm and then a unique activation code generated for that system. This code will then have to be used to activate the application. Note that the node Id or the activation code is unique because they comprised of a combination of the CPU Id and MAC Id of the system on which the application was to be installed and executed.
This article is published as part of the IDG Contributor Network. Want to Join?