Library tutorials & articles

Using WMI From Managed Code

Working with WMI in .NET

This article was originally published on DNJ Online
DNJ

Programs written in a .NET language can access WMI through the COM Inter-op technology. To demonstrate this we’ll look at a C# application that uses the WMI Win32_Printer class to create a new managed object and put it in the repository; get an existing object and modify its properties; run a method of a particular class; and delete an object from the repository.

WMI is exposed to .NET through the System.Management library. In order to use it we need to add a reference to System.Management.dll. We then start by creating the class WMIHelper:

class WMIHelper {
  private ManagementScope managementScope = null;
  ...
}

Before we can start any WMI activity we need to create a connection to the WMI repository either on the local or a remote machine. If we are connecting to a local machine we create a default ConnectionOptions class instance. If we’re going for a remote machine we set the username and password to specify a user who has rights to access WMI functionality (typically a member of Administrators group). Once this is done the ManagementScope can be created using the WMI path and ConnectionOptions. The Win32_Printer class, as with all WMI Win32 classes, is located under root\cimv2 on the local or remote machine:

public WMIHelper( string serverName, string adminUser, 
			string adminUserPassword) 
{ 
	try 
	{ 
		ConnectionOptions connectionOptions = 
				   new ConnectionOptions(); 
		string wmiPath; 
		if(serverName == null || serverName.Length == 0 || 
		   adminUser == null || adminUser.Length == 0 || 
				adminUserPassword == null || 
				adminUserPassword.Length == 0) 
			{ 
			   //specify WMI path for local machine 
			   wmiPath = @"root\cimv2";  
			}  
			else 
			{  
				//set connection parameters for remote machine  
				connectionOptions.Username = adminUser;  
				connectionOptions.Password = adminUserPassword;  
				//specify WMI path for remote machine 
				wmiPath = String.Format(
						@"\\{0}\root\cimv2", serverName);  
			}  
		managementScope = new ManagementScope(wmiPath, connectionOptions); 
	}  
		catch( Exception ex) 
	{ 
		throw new Exception( 
		  String.Format( "WMI exception: {0}", ex.Message));  
	}
}

From this point on the code will work with both local and remote modes.

Creating a new object

So let’s create a new printer object and put it into the repository. The relevant properties for the Win32_Printer class are as follows:

class Win32_Printer : CIM_Printer  {  
     string DeviceID;  
     string DriverName;  
     string PortName;  
     boolean Shared;  
     string ShareName; 
}; 

First we create the helper method InitClass which takes the WMI class name (Win32_Printer in our case) and, using the management scope initialised in the constructor, returns a ManagementClass:

private ManagementClass InitClass( string className)  {  
   //specify Printer class management path  
   ManagementPath managementPath = 
				 new ManagementPath(className);  
   try  
   {  
	  //create new WMI management class  
	  return new ManagementClass(

				 managementScope, managementPath, null);  
   }  
   catch ( Exception ex)  
   { 
      throw new Exception( 
         String.Format( 
        "WMI exception: {0}", ex.Message));  
   }
}

Here’s the code which adds a new printer object to the repository based on its name, the name of the printer driver and the port, and whether we want it to be shared or not. The function returns true if the printer is successfully added, or false if there is a problem:

public bool AddPrinter( 
               string printerName, string printerDriver,  
               string portName, bool sharedPrinter)  
{  
	bool result = false;  
	try  
	{ 
      //init Win32_Printer class 
    	ManagementClass printerClass = 
                        InitClass( "Win32_Printer"); 
      //create new Win32_Printer object 
    	ManagementObject printerObject = 
                   printerClass.CreateInstance(); 
      //set port parameters 
		if (portName == null || portName.Length == 0) 
		    printerObject[ "PortName"] = "LPT1:"; 
		else 
		{ 
			if (portName[portName.Length - 1] != ':') 
				printerObject[ "PortName"] = (portName + ":"); 
			else 
				printerObject[ "PortName"] = portName; 
		}
		//set driver and device names 
		printerObject[ "DriverName"] = printerDriver; 
	
		printerObject[ "DeviceID"] = printerName; 
		//set sharing 
		if (sharedPrinter) 
		{ 
			printerObject[ "Shared"] = sharedPrinter; 
			printerObject[ "ShareName"] = printerName; 
		} 
		// specify put options: update or create 
		PutOptions options = new PutOptions(); 
		options.Type = PutType.UpdateOrCreate; 
			//put a newly created object to WMI objects set 
		printerObject.Put(options); 
		
		result = true; 
	} 
	catch ( Exception ex) 
	{ 
	    throw new Exception(  String.Format( "WMI exception: {0}", ex.Message)); 
	} 
  return result; 
}

We start by creating the appropriate ManagementClass with the help of InitClass, and then create a new instance in printerObject. Next we set the necessary properties for the object, and then we Put the object into the repository. Prior to doing that we set its PutOptions to ‘UpdateOrCreate’, which means ‘save the object whether this involves updating an existing object or creating a new one’. Once this is done a new printer will appear in the system.

Comments

  1. 18 Mar 2009 at 02:59
    Hi, This article is very nice. I became a member of this forum after reading this article. We have different approaches to manage enterprise systems (systems in remote or distriputed over network). like Windows Service, Web Service, Remote Management services. How is WMI different/better than those technologies. It will be good if you list the technologies before WMI and the difference Thanks a lot for your good work Regards, Palanivel

Leave a comment

Sign in or Join us (it's free).

Andriy Klyuchevskyy
AddThis

Related podcasts

  • A Practical Look at Silverlight 2 Part 1

    Now that Silverlight 2 is at the Olympics and making a big splash, we wanted to explore this fascinating technology more. Microsoft Silverlight 2 is a cross-browser, cross-platform, and cross-device plug-in for delivering the next generation of .NET based media experiences and rich interactive ap...

Events coming up

  • Nov 18

    15 Minutes of Fame

    Dresher, United States

    This is a yearly tradition. We select 10 of the favorite speakers from monthly meetings, code camps, and hands on labs. Each one does a 15 minute talk on their favorite .NET technology. This is our 10th anniversary so we plan a gala event with special prizes and refreshments.

Want to stay in touch with what's going on? Follow us on twitter!