- HDD Serial Number(s)
- HDD Sizes
- HDD Free Space
- CPU Serial Number(s)
- CPU Clock Speed
- CPU Socket Type
- Network Adapter MAC Address
- Network Adapter Default Gateway
And much more. In this tutorial we will be looking at some of the information that can be retrieved using WMI, along with Windows Query Language, or WQL. though this tutorial isn't an all inclusive tutorial on the topic, we will look at enough to at least give you a good foundation for using WMI in your applications.
In this tutorial we will see how to retrieve HDD information, CPU information, and Network Adapter information. For this tutorial there are 3 classes we will be using to retrieve this information for our applications:
Of course there are many more WMI Classes that are available, and if I were to try and cover all of them this would be a 20 page tutorial. All the items we will be using require a reference to the System.Management Namsepace provided in the .Net framework
Win32_LogicalDiskClass
The Win32_LogicalDisk WMI class represents a data source that resolves to an actual local storage device on a computer system running Windows. In this section we will do a few tasks such as:
- Retrieve selected HDD serial number
- Retrieve selected HDD free space
- Retrieve HDD initial size
The first task, getting the serial number of a selected HDD (as with all the tasks in this section) we will be passing a drive letter to our method, with that drive letter we will query the system using the DeviceID Property of the Win32_LogicalDisk class. Once we have done that we have access to many properties, which we will use in this section. First, to receive the serial number:
CODE
/// <summary>
/// method to retrieve the selected HDD's serial number
/// </summary>
/// <param name="strDriveLetter">Drive letter to retrieve serial number for</param>
/// <returns>the HDD's serial number</returns>
public string GetHDDSerialNumber(string drive)
{
//check to see if the user provided a drive letter
//if not default it to "C"
if (drive == "" || drive == null)
{
drive = "C";
}
//create our ManagementObject, passing it the drive letter to the
//DevideID using WQL
ManagementObject disk = new ManagementObject("Win32_LogicalDisk.DeviceID=\"" + drive + ":\"");
//bind our management object
disk.Get();
//return the serial number
return disk["VolumeSerialNumber"].ToString();
}
As you can see, we check the DevideID to ensure we are looking at the proper HDD, then we use the Get Method of the ManagementObject Class to bind our management object, allowing us to retrieve the attributes we are looking for.
The nice thing about the Win32_LogicalDisk Class is once you learn to retrieve one attribute or property, the rest are easily retrieved, such as retrieving the free space of a HDD:
CODE
/// <summary>
/// method to retrieve the HDD's freespace
/// </summary>
/// <param name="drive">Drive letter to get free space from (optional)</param>
/// <returns>The free space of the selected HDD</returns>
public double GetHDDFreeSpace(string drive)
{
//check to see if the user provided a drive letter
//if not default it to "C"
if (drive == "" || drive == null)
{
drive = "C";
}
//create our ManagementObject, passing it the drive letter to the
//DevideID using WQL
ManagementObject disk = new ManagementObject("Win32_LogicalDisk.DeviceID=\"" + drive + ":\"");
//bind our management object
disk.Get();
//return the free space amount
return Convert.ToDouble(disk["FreeSpace"]);
}
And retrieving the initial size of a selected HDD, like so:
CODE
/// <summary>
/// method to retrieve the HDD's size
/// </summary>
/// <param name="drive">Drive letter to get free space from (optional)</param>
/// <returns>The free space of the selected HDD</returns>
public double getHDDSize(string drive)
{
//check to see if the user provided a drive letter
//if not default it to "C"
if (drive == "" || drive == null)
{
drive = "C";
}
//create our ManagementObject, passing it the drive letter to the
//DevideID using WQL
ManagementObject disk = new ManagementObject("Win32_LogicalDisk.DeviceID=\"" + drive + ":\"");
//bind our management object
disk.Get();
//return the HDD's initial size
return Convert.ToDouble(disk["Size"]);
}
You will notice in the previous 3 methods the drive letter is actually optional. We check to see if a drive was provided, and if it wasnt then we default it to the users "C" drive, which is usually the OS drive on most computers.
Win32_NetworkAdapterConfiguration Class
The Win32_NetworkAdapterConfiguration WMI class represents the attributes and behaviors of a network adapter. This class includes extra properties and methods that support the management of the TCP/IP and IPX (Internetwork Packet Exchange) protocols.
With this class we can get information such as:
- MAC Address
- Default IP Gateway
- IP Enabled Status
In the following examples we will be introduced to the ManagementObjectCollection Class. This class represents different collections of management objects that can be retrieved through WMI. We will then loop through all the items in our collection to retrieve information about the network adapter on that particular system.
First we will look at how to retrieve the systems MAC address. In these examples we will onl;y be retrieving information from the first network adapter we find, they can easily be modified to create a collection of network adapter information.
CODE
/// <summary>
/// Returns MAC Address from first Network Card in Computer
/// </summary>
/// <returns>MAC Address in string format</returns>
public string FindMACAddress()
{
//create out management class object using the
//Win32_NetworkAdapterConfiguration class to get the attributes
//of the network adapter
ManagementClass mgmt = new ManagementClass("Win32_NetworkAdapterConfiguration");
//create our ManagementObjectCollection to get the attributes with
ManagementObjectCollection objCol = mgmt.GetInstances();
string address = String.Empty;
//loop through all the objects we find
foreach (ManagementObject obj in objCol)
{
if (address == String.Empty) // only return MAC Address from first card
{
//grab the value from the first network adapter we find
//you can change the string to an array and get all
//network adapters found as well
//check to see if the adapter's IPEnabled
//equals true
if ((bool)obj["IPEnabled"] == true)
{
address = obj["MacAddress"].ToString();
}
}
//dispose of our object
obj.Dispose();
}
//replace the ":" with an empty space, this could also
//be removed if you wish
address = address.Replace(":", "");
//return the mac address
return address;
}
In the first example, along with the others in this section, we will be using the GetInstances Method of the ManagementObjectCollection Class to retrieve all instances of the specified class, in this case the Win32_NetworkAdapterConfiguration class.
Now lets look at retrieving the default IP gateway of a network adapter. As with the first example, we will be using the first adapter we find, as long as its IPEnabled Property is true:
CODE
/// <summary>
/// method to retrieve the network adapters
/// default IP gateway using WMI
/// </summary>
/// <returns>adapters default IP gateway</returns>
public string GetDefaultIPGateway()
{
//create out management class object using the
//Win32_NetworkAdapterConfiguration class to get the attributes
//of the network adapter
ManagementClass mgmt = new ManagementClass("Win32_NetworkAdapterConfiguration");
//create our ManagementObjectCollection to get the attributes with
ManagementObjectCollection objCol = mgmt.GetInstances();
string gateway = String.Empty;
//loop through all the objects we find
foreach (ManagementObject obj in objCol)
{
if (gateway == String.Empty) // only return MAC Address from first card
{
//grab the value from the first network adapter we find
//you can change the string to an array and get all
//network adapters found as well
//check to see if the adapter's IPEnabled
//equals true
if ((bool)obj["IPEnabled"] == true)
{
gateway = obj["DefaultIPGateway"].ToString();
}
}
//dispose of our object
obj.Dispose();
}
//replace the ":" with an empty space, this could also
//be removed if you wish
gateway = gateway.Replace(":", "");
//return the mac address
return gateway;
}
Win32_Processor
This class allows us to retrieve properties of the processor running on a Windows based computer. On a system with multiple processors, one instance of the Win32_Processor class exists for each processor. Using this class allows us to retrieve information about the processor such as:
- CPU ID
- CPU Manufacturer
- CPU Status
- CPU Current Clock Speed
As with the other class examples, we will only be getting information from the first processor we find, they too can be modified to return information for all processors in a system. In these examples we will also be using the GetInstances Method, as each processor will have it's own instance. First, getting the CPU ID:
CODE
/// <summary>
/// Return processorId from first CPU in machine
/// </summary>
/// <returns>[string] ProcessorId</returns>
public string GetCPUId()
{
string cpuInfo = String.Empty;
//create an instance of the Managemnet class with the
//Win32_Processor class
ManagementClass mgmt = new ManagementClass("Win32_Processor");
//create a ManagementObjectCollection to loop through
ManagementObjectCollection objCol = mgmt.GetInstances();
//start our loop for all processors found
foreach(ManagementObject obj in objCol)
{
if(cpuInfo == String.Empty)
{
// only return cpuInfo from first CPU
cpuInfo = obj.Properties["ProcessorId"].Value.ToString();
}
}
return cpuInfo;
}
To get the manufacturer, we will return the Manufacturer property of the first instance we find:
CODE
/// <summary>
/// method for retrieving the CPU Manufacturer
/// using the WMI class
/// </summary>
/// <returns>CPU Manufacturer</returns>
public string GetCPUManufacturer()
{
string cpuMan = String.Empty;
//create an instance of the Managemnet class with the
//Win32_Processor class
ManagementClass mgmt = new ManagementClass("Win32_Processor");
//create a ManagementObjectCollection to loop through
ManagementObjectCollection objCol = mgmt.GetInstances();
//start our loop for all processors found
foreach (ManagementObject obj in objCol)
{
if (cpuMan == String.Empty)
{
// only return manufacturer from first CPU
cpuMan = obj.Properties["Manufacturer"].Value.ToString();
}
}
return cpuMan;
}
Processors today are vastly different than they were 20 years ago, today people are over clocking their processors to get more power out of them. That being the case, some systems might be running at a higher clock speed than what is listed on the system information, so we will use the CurrentClockSpeed Property to retrieve the current clock speed of the first instance we find:
CODE
/// <summary>
/// method to retrieve the CPU's current
/// clock speed using the WMI class
/// </summary>
/// <returns>Clock speed</returns>
public int GetCPUCurrentClockSpeed()
{
int cpuClockSpeed = 0;
//create an instance of the Managemnet class with the
//Win32_Processor class
ManagementClass mgmt = new ManagementClass("Win32_Processor");
//create a ManagementObjectCollection to loop through
ManagementObjectCollection objCol = mgmt.GetInstances();
//start our loop for all processors found
foreach (ManagementObject obj in objCol)
{
if (cpuClockSpeed == 0)
{
// only return cpuStatus from first CPU
cpuClockSpeed = Convert.ToInt32(obj.Properties["CurrentClockSpeed"].Value.ToString());
}
}
//return the status
return cpuClockSpeed;
}
As stated before this isnt an all exhaustive list of classes and ways to use the WMI class, there are hundreds (maybe more) items that can be retrieved about a system using this class. The items in this tutorial, and the attached class file, will give you a good jump start on using the WMI class in your applications.
I will be including the class file I created for this tutorial, the class itself is under the GNU General Public License, meaning you can modify and distribute it as you see fit, but the license information must remain intact. I hope you found this tutorial useful and informative, and thank you for reading.
Happy Coding!
Click to view attachment