dotnet Exception Handling

.NET Exceptions – System.Management.ManagementException

Moving along through the detailed .NET Exception Handling series, today we will be exploring the System.Management.ManagementException. A ManagementException is thrown when something goes wrong while working with the Windows Management Instrumentation (WMI) components contained within the System.Management namespace. WMI essentially allows scripts and applications to perform queries against local or remote systems, devices, and even other apps. These queries can retrieve a variety of information, including logical disk data, CPU utilization, database connectivity, and so forth.

Throughout this article we’ll explore the ManagementException by looking at where it sits in the larger .NET exception hierarchy. We’ll also look at some fully-functional C# sample code to illustrate not only how WMI works to retrieve system information, but also how invalid queries or issues might result in ManagementExceptions in your own code, so let’s get going!

The Technical Rundown

All .NET exceptions are derived classes of the System.Exception base class, or derived from another inherited class therein. The full exception hierarchy of this error is:

Full Code Sample

Below is the full code sample we’ll be using in this article. It can be copied and pasted if you’d like to play with the code yourself and see how everything works.

When Should You Use It?

Windows Management Instrumentation (WMI) allows applications and scripts to manage Windows-based systems and devices, both locally and remotely. Once a connection is established to a system, WMI can be used to perform SQL-like queries, which effectively provides an API to the executing application, allowing it to retrieve data or perform changes to the underlying system. Covering the whole of the WMI infrastructure is well beyond the scope of this little tutorial, but feel free to check out the official documentation for more information.

However, in order to see how a ManagementException might be thrown, we need to get into the basics of WMI and how it can be manipulated via code. Before we access system information programmatically, it helps to look at some system data through a visual tool. Thankfully, most newer versions of Windows already include such a tool, known as the Windows Management Instrumentation Tester (or wbemtest.exe). To launch it, open your Start menu and search for wbemtest.exe, then press enter to run the application.

Once open, let’s start by connecting to the local computer. Click Connect and verify that root\cimv2 is entered into the Namespace field, then click Connect in this second dialog. Now, click Open Class and in the Target Class Name field enter Win32_LogicalDisk and click OK. This should bring up an Object Editor screen for the Win32_LogicalDisk class of data found within your local system.

As you can see from the titles above the main boxes, there are some Qualifiers, Properties, and even some Methods that can be performed via WMI to query or adjust the local disk. We won’t be doing anything harmful in this tutorial, since we’ll just be retrieving data via the Properties, so feel free to scroll through those and see what sort of property values exist for your local disks.

Now, let’s move onto the sample code to see how we can perform similar queries using C#. We begin with a custom Manager class, which was created to help “manage” the various WMI-related objects needed to establish a connection and perform queries:

There are a handful of properties for the Manager class, but the important one is the ManagementObjectSearcher Searcher property, which is the fundamental class we’ll be using to perform queries. To create a new ManagementObjectSearcher instance we need to specify a ManagementScope, which is effectively the path to the specific system/computer, along with the namespace within said computer, that will be queried. root\cimv2 is the primary namespace, and in this case, I7 is the name of the computer that I’m querying, so that’s where we get the ScopePathDefault constant value of "\\\\I7\\root\\cimv2".

The ManagementObjectSearcher instance also needs a query, which we create by passing a string to a new ObjectQuery instance. Both the OutputProperty(string property) and DumpResults() methods are fairly simple and self-explanatory, so we won’t get into those.

Now, our goal is to retrieve local disk information, specifically regarding storage capacity. To format the produced output a bit better, we’ve also created a simple extension method of ToStorageString(this ulong value):

This method extends ulong (i.e. UInt64) values, making it easy to convert these large values into recognizable byte-based output formats, such as MB, GB, TB, etc.

Now that everything is setup, let’s use our Manager class and the ToStorageString(this ulong value) extension method to query our disks and get some info. We start with the GetDiskInfo() method:

Here we perform a simple query of getting all data from the Win32_LogicalDisk class (which we explored with the wbemtest.exe tool), then loop through the resulting data and get some specific property values to produce a readable log output. The result of executing this method on my local system shows all three of my primary logical disks and their current free space/capacity:

Cool! However, WMI is capable of much more, so let’s expand a bit and query every field in the Win32_LogicalDisk class and output it, just to see the values of everything we could potentially want to look at. This is performed in the GetFullDiskInfo() method, which also uses the Manager.DumpResults() method:

Executing this code produces the full, formatted list of property key/value pairs for each local disk:

Finally, everything has worked just as expected up to this point, but let’s see what happens if we make a mistake in our query or order of execution when creating a ManagementObjectSearcher. To illustrate this we have the GetDiskInfo_InvalidQuery() method:

This may look similar to the GetDiskInfo() method (and it is), but the subtle difference is the class we’re querying is Win32_PhysicalDisk instead of Win32_LogicalDisk. Executing this method results in the following output:

As it happens, Win32_PhysicalDisk is not a valid class in WMI, so a ManagementException is thrown indicating as much.

To get the most out of your own applications and to fully manage any and all .NET Exceptions, check out the Airbrake .NET Bug Handler, offering real-time alerts and instantaneous insight into what went wrong with your .NET code, along with built-in support for a variety of popular development integrations including: JIRA, GitHub, Bitbucket, and much more.