I've been writing small WMI applications off and on for the past few years and have always found that writing such an application in .NET has always seemed somewhat cumbersome. I couldn't help but think there was a better way to write a WMI application in .NET. So I started out to search the Internet for anything I could find that might help speed up the development process. Everywhere I turned I found article after article showing people how to use the
System.Management namespace within .NET to accomplish their goals. Some of these writings were very good, and some could probably use a little more work. But one thing they always had in common, were the strings of comments after the article asking “How do I do ‘this’…” or “Is it possible to do ‘this’…”. Which led me to think, did this article really answer the questions people are having? The answer I found to my own question was, yes, and no.
One of the problems with writing a WMI application in .NET is that there isn't a direct way to work with the properties and methods of the built-in classes. Every solution ends with developers referencing properties via a string index within a
ManagementObject oMngObject = MyObejctCollection;
lblDemo.Text = oMngObject[“Manufacturer”];
This being a completely valid method for working with WMI properties, it doesn't do much good if you don't know the name of the property you're trying to access. This is where
EasyWMI comes in.
Breakdown of EasyWMI
I developed the
EasyWMI class library to help speed up the development process of developing WMI driven applications. It includes a large percentage of all of the Win32 classes within the root/cimv2 namespace. The library consists of two main parts: controllers and models. The models are the
Win32 classes pulled directly from WMI within Windows and contain all the properties and methods for each. The controllers are what create and populate all of the models for each class. For every model there is a corresponding controller that accompanies it. The naming scheme for the controllers is the same naming scheme as the models without the preceding
Win32_ prefix. For example, the
Win32_Process class has a corresponding controller named
Process. One thing to note when using the source of
EasyWMI, is that I did not physically write all of the models and controllers. I actually threw together a code generator using CodeDOM specifically for this purpose. So when working with the actual source, be warned, indentations may be a little off, making it a little awkward to read, but not difficult.
Using the Code
EasyWMI is very simple. Create a new instance of the class controller you wish to use and run the
SelectAll() method. Each controller contains 5 overloaded constructors; the default constructor assumes “localhost”.
ComputerSystem CS = new ComputerSystem();
IList<win32_computersystem /> CSCollection = CS.SelectAll();
Win32_ComputerSystem MyCS = CSCollection;
SelectAll() returns a generic
IList<t /> collection of type
Win32_CLASSNAME. Some classes will only return one item within the collection, such as
OperatingSystem, for example. You now have access to all of the methods and properties for that particular object of the
Win32_ComputerSystem type. For classes that return more than one object, you can simply use a
foreach loop to iterate through the collection.
static void DisplayLogicalDisks(IList<win32_logicaldisk /> Drives)
foreach (Win32_LogicalDisk LogicalDisk in Drives)
Console.WriteLine("Drive " + LogicalDisk.DeviceID);
Console.WriteLine(" Volume:\t\t" + LogicalDisk.VolumeName);
Console.WriteLine(" Size:\t\t" + ConvertToMB(LogicalDisk.Size));
Console.WriteLine(" Free Space:\t\t" + ConvertToMB
Console.WriteLine(" File System:\t" + LogicalDisk.FileSystem);
Console.WriteLine(" Caption:\t\t" + LogicalDisk.Caption);
Console.WriteLine(" Serial:\t\t" + LogicalDisk.VolumeSerialNumber);
catch (Exception ex)
Console.WriteLine("Error retrieving information.");
Console.WriteLine("Message: " + ex.Message);
Now you have an idea of how simple it is to access properties for each of the Win32 classes, but what about using their methods? Simple, use them the way you would use any method.
Process SysProcess = new Process();
IList<win32_process /> Processes = SysProcess.SelectAll();
foreach (Win32_Process Process in Processes)
if (Process.Name == "iexplore.exe")
Process.GetOwner(out Domain, out Username);
You can also specify a different query to use instead of the default
select * from.
CS = new ComputerSystem(ComputerName);
CS.EasyWMICfgUsername = @"yourdomain\username";
CS.EasyWMICfgPassword = "password";
CS.EasyWMICfgQuery = "select Manufacturer from";
CSCollection = CS.SelectAll();
You may notice I call the
SetScope() method after I set some configuration options. You'll need to run the
SetScope() method anytime you change any of the configuration options before you run the
Although this may not be the most complete and yet still not the best way to interface with WMI using .NET, I hope this helps simplify working with WMI and speed up your development process.
No updates as of yet.