How to: Make the State of an Application Manageable

The following code example demonstrates how to create a decoupled WMI provider. This provider exposes configuration information for a mortgage calculator implemented as a Windows Forms application. The configuration information is stored in an XML file. The WMI provider reads and writes to that file.

Example

The following code implements the WMI provider portion of the example. The mortgage calculator portion is available Managed Application Code. The example follows a series of steps to implement the WMI provider. The steps are described in the embedded source code comments and enumerated here to provide you with an overview of what is required.

  1. Declare that this assembly implements a WMI Provider by using the WmiConfigurationAttribute attribute. This is where you specify the namespace the provider will be exposed through and the fact that it is a decoupled provider.
  2. Derive a class from DefaultManagementInstaller. This step is required to enable you to later use installutil.exe to register the provider and include the appropriate, corresponding MOF information in the WMI repository.
  3. Specify the ManagementEntityAttribute attribute on your provider implementation class. This declares that the class will be exposed as a WMI class and it is where you name the class.
  4. Specify the ManagementBindAttribute attribute on your constructor. This binds an instance of the class to an instance of the manageable entity. You set the key values in the constructor.
  5. Specify the ManagementKeyAttribute attribute and establish the class properties that will act as unique keys for instances of your WMI class.
  6. Use the ManagementProbeAttribute, ManagementConfigurationAttribute and ManagementTaskAttribute attributes to declare methods that implement, respectively, read-only properties, read-write properties and methods on your class.
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Configuration.Install;
using System.Management;
using System.Management.Instrumentation;
using System.Text;
using System.Xml;
using DecoupledWMIProvider;

// Specify that this code is used to to create an assembly 
// that contains a WMI Provider.
// Use the assembly:WmiConfiguration attribute to define the WMI //namespace, the hosting model, and the security of the 
//WMI provider.
// The attribute below specifies that the class this provider
// exposes to WMI will be in the root/MortgageCalc namespace.
[assembly: WmiConfiguration("root/MortgageCalc", HostingModel = ManagementHostingModel.Decoupled, IdentifyLevel = false)]

// This is the installer class that installs an instrumented assembly.
// To use the default project installer, simply derive a class from
// DefaultManagementInstaller.  No methods need to be overridden.
[System.ComponentModel.RunInstaller(true)]
public class TheInstaller : DefaultManagementInstaller
{ }
namespace DecoupledWMIProvider
{
    // Use the ManagementEntity attribute on the class to specify that 
    // this class contains management information that is 
    // available from a provider.
    
    [ManagementEntity(Name = "MortgageCalc")]
    [ManagementQualifier("Description", Value = "Allows you to read and set configuration settings for the MortgageCalc application.")]
    public class MortgageCalcWMIProvider
    {
        
        //private static MortgageCalcWMIProvider _instance;
        private int _id;

        // Use the ManagementBind attribute to specify
        // that this constructor is used to attach a
        // class instance to a specific WMI instance.
        // The constructor should set the values of the
        // Key properties of the WMI instance.
        [ManagementBind]
        public MortgageCalcWMIProvider(int id)
        {
            this._id = id;
        }

        // Use the Task attribute to specify that a method
        // is exposed to WMI through this provider. Consumers will be
        // able to execute this method through WMI.
        [ManagementTask]
        [ManagementQualifier("Description",Value = "Sets the default highest and lowest loan amounts.")]
        public void SetDefaultLoanValues()
        {
            System.IO.StreamWriter configOutput =
                    new System.IO.StreamWriter("mortgageCalcConfig.xml");
            XmlTextWriter writer = new XmlTextWriter(configOutput);
            writer.WriteStartDocument();
            writer.WriteStartElement("MortgageCalcConfig");
            writer.WriteElementString("highestLoanAmount", "500000");
            writer.WriteElementString("lowestLoanAmount", "8000");
            writer.WriteEndElement();
                            
            configOutput.Close(); 
        }

        // Use the Key attribute to specify this property is used as
        // the key identifier of this class and for the WMI instances
        // of this class.  This property must be unique for each class
        // instance.
       
        [ManagementQualifier("Description", Value = "Returns the Id for the process running the MortgageCalc application.")]
        [ManagementKey]
        public int Id
        {
            get { return this._id;}
        }

        // Use the ManagementConfiguration attribute to specify that a property
        // is a read/write property in the provider. Consumers will be
        // able to get and set this property value through WMI.
        [ManagementConfiguration]
        [ManagementQualifier("Description", Value = "Gets or sets the highest loan amount allowed.")]
        public double highestLoanAmount
        {
            get
            {
                System.IO.StreamReader configInput =
                    new System.IO.StreamReader("mortgageCalcConfig.xml");

                XmlTextReader reader = new XmlTextReader(configInput);
                configInput.Close();
                reader.ReadToDescendant("highestLoanAmount");
                return double.Parse(reader.ReadString());                       
            }
            set
            {
                System.IO.StreamWriter configOutput =
                    new System.IO.StreamWriter("mortgageCalcConfig.xml");

                XmlTextWriter writer = new XmlTextWriter(configOutput);
                writer.WriteElementString("highestLoanAmount", value.ToString());
                writer.Close();
            }
        }
        [ManagementConfiguration]
        [ManagementQualifier("Description", Value = "Gets or sets the lowest loan amount allowed.")]
        public double LowestLoanAmount
        {
            get
            {
                System.IO.StreamReader configInput =
                  new System.IO.StreamReader("mortgageCalcConfig.xml");

                XmlTextReader reader = new XmlTextReader(configInput);
                configInput.Close();
                reader.ReadToDescendant("lowestLoanAmount");
                return double.Parse(reader.ReadString());
            }
            set
            {
                System.IO.StreamWriter configOutput =
                  new System.IO.StreamWriter("mortgageCalcConfig.xml");

                XmlTextWriter writer = new XmlTextWriter(configOutput);

                writer.WriteElementString("highestLoanAmount", value.ToString());
                writer.Close();
            }
        }
        
        // Use the Probe attribute to specify that a property
        // is a read-only property in the provider. Consumers will be
        // able to get, but not set, this property value through WMI.
        [ManagementProbe]
        [ManagementQualifier("Description", Value = "Gets the last time that the configuration settings were modified.")]
        [ManagementQualifier("write")]
        public DateTime SettingsLastModified
        {
            get
            {
                System.IO.FileInfo fileInfo = new System.IO.FileInfo("mortgageCalcConfig.xml");
                return fileInfo.LastWriteTime;
            }
        }
    }
}

After compiling the code, you must run installutil.exe to register the provider with WMI. Because this is a decoupled provider, the application must be running to use the WMI class.

See Also

Reference

System.Management.Instrumentation

Send comments about this topic to Microsoft.

Copyright © 2007 by Microsoft Corporation. All rights reserved.