Sunday, July 12, 2009

Using WMI for building better applications

There was a couple of stack overflow question the other day that got my attention: How to find out if a user has administer privileges? and How to programmatically discover mapped network drives on system and their server names? My fist thought was WMI, and it got me thinking about how little WMI is discussed, I’ve never seen a conference session about it, or a session at code camp on it. Yet if your doing any serious system development it’s almost required.

For starters what is WMI?

According to Microsoft Technet “Windows Management Instrumentation (WMI) is the primary management technology for Microsoft® Windows® operating systems. It enables consistent and uniform management, control, and monitoring of systems throughout your enterprise….” see Microsoft Technet

So what dose this mean for a .NET developer?

You can access WMI though the System.Management namespace and can be used for finding out just about anything you want to know about your computer and Microsoft network. For example what drives do you have mapped?

   1: using System;
   2: using System.Management;
   3: using System.Windows.Forms;
   4:  
   5: namespace WMISample
   6: {
   7:     public class MyWMIQuery
   8:     {
   9:         public static void Main()
  10:         {
  11:             try
  12:             {
  13:                 ManagementObjectSearcher searcher = 
  14:                     new ManagementObjectSearcher("root\\CIMV2", 
  15:                     "SELECT * FROM Win32_MappedLogicalDisk"); 
  16:  
  17:                 foreach (ManagementObject queryObj in searcher.Get())
  18:                 {
  19:                     Console.WriteLine("-----------------------------------");
  20:                     Console.WriteLine("Win32_MappedLogicalDisk instance");
  21:                     Console.WriteLine("-----------------------------------");
  22:                     Console.WriteLine("Access: {0}", queryObj["Access"]);
  23:                     Console.WriteLine("Availability: {0}", queryObj["Availability"]);
  24:                     Console.WriteLine("BlockSize: {0}", queryObj["BlockSize"]);
  25:                     Console.WriteLine("Caption: {0}", queryObj["Caption"]);
  26:                     Console.WriteLine("Compressed: {0}", queryObj["Compressed"]);
  27:                     Console.WriteLine("ConfigManagerErrorCode: {0}", queryObj["ConfigManagerErrorCode"]);
  28:                     Console.WriteLine("ConfigManagerUserConfig: {0}", queryObj["ConfigManagerUserConfig"]);
  29:                     Console.WriteLine("CreationClassName: {0}", queryObj["CreationClassName"]);
  30:                     Console.WriteLine("Description: {0}", queryObj["Description"]);
  31:                     Console.WriteLine("DeviceID: {0}", queryObj["DeviceID"]);
  32:                     Console.WriteLine("ErrorCleared: {0}", queryObj["ErrorCleared"]);
  33:                     Console.WriteLine("ErrorDescription: {0}", queryObj["ErrorDescription"]);
  34:                     Console.WriteLine("ErrorMethodology: {0}", queryObj["ErrorMethodology"]);
  35:                     Console.WriteLine("FileSystem: {0}", queryObj["FileSystem"]);
  36:                     Console.WriteLine("FreeSpace: {0}", queryObj["FreeSpace"]);
  37:                     Console.WriteLine("InstallDate: {0}", queryObj["InstallDate"]);
  38:                     Console.WriteLine("LastErrorCode: {0}", queryObj["LastErrorCode"]);
  39:                     Console.WriteLine("MaximumComponentLength: {0}", queryObj["MaximumComponentLength"]);
  40:                     Console.WriteLine("Name: {0}", queryObj["Name"]);
  41:                     Console.WriteLine("NumberOfBlocks: {0}", queryObj["NumberOfBlocks"]);
  42:                     Console.WriteLine("PNPDeviceID: {0}", queryObj["PNPDeviceID"]);
  43:  
  44:                     if(queryObj["PowerManagementCapabilities"] == null)
  45:                         Console.WriteLine("PowerManagementCapabilities: {0}", queryObj["PowerManagementCapabilities"]);
  46:                     else
  47:                     {
  48:                         UInt16[] arrPowerManagementCapabilities = (UInt16[])(queryObj["PowerManagementCapabilities"]);
  49:                         foreach (UInt16 arrValue in arrPowerManagementCapabilities)
  50:                         {
  51:                             Console.WriteLine("PowerManagementCapabilities: {0}", arrValue);
  52:                         }
  53:                     }
  54:                     Console.WriteLine("PowerManagementSupported: {0}", queryObj["PowerManagementSupported"]);
  55:                     Console.WriteLine("ProviderName: {0}", queryObj["ProviderName"]);
  56:                     Console.WriteLine("Purpose: {0}", queryObj["Purpose"]);
  57:                     Console.WriteLine("QuotasDisabled: {0}", queryObj["QuotasDisabled"]);
  58:                     Console.WriteLine("QuotasIncomplete: {0}", queryObj["QuotasIncomplete"]);
  59:                     Console.WriteLine("QuotasRebuilding: {0}", queryObj["QuotasRebuilding"]);
  60:                     Console.WriteLine("SessionID: {0}", queryObj["SessionID"]);
  61:                     Console.WriteLine("Size: {0}", queryObj["Size"]);
  62:                     Console.WriteLine("Status: {0}", queryObj["Status"]);
  63:                     Console.WriteLine("StatusInfo: {0}", queryObj["StatusInfo"]);
  64:                     Console.WriteLine("SupportsDiskQuotas: {0}", queryObj["SupportsDiskQuotas"]);
  65:                     Console.WriteLine("SupportsFileBasedCompression: {0}", queryObj["SupportsFileBasedCompression"]);
  66:                     Console.WriteLine("SystemCreationClassName: {0}", queryObj["SystemCreationClassName"]);
  67:                     Console.WriteLine("SystemName: {0}", queryObj["SystemName"]);
  68:                     Console.WriteLine("VolumeName: {0}", queryObj["VolumeName"]);
  69:                     Console.WriteLine("VolumeSerialNumber: {0}", queryObj["VolumeSerialNumber"]);
  70:                 }
  71:             }
  72:             catch (ManagementException e)
  73:             {
  74:                 MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
  75:             }
  76:         }
  77:     }
  78: }

for a lot of developers this doesn't mater one way or another, for most winform or WPF apps you don’t need it, if your doing web development their is almost never going to be a reason to touch WMI.

One exception to this is if your working on an intranet application. How many time have you seen internal application that use a database to manage employees, there roles, etc. and then manage there active directory separately, why not just use active directory to do both?

If this seems a little obscure don’t worry there is a tool to do most of the heavy lifting for you.

The WMI Code Creator v1.0

WMI

It builds WMI queries, execute them, browse the local computers namespace, etc. for more information see the product overview.

No comments: