Events

[Previous] [Next]

Any practical management application must be largely driven by events. This is true both for a reactive management application (in which components are fixed after they break) and a preventive management application (in which components are fixed before they break). WMI has an extensive set of event-related features that require minimum effort on your part to use. In this section, I will look at what WMI provides and then describe how you can turn your service into an enterprise class application capable of being managed in a large and complex environment, or suitable for use in situations where remote service and support are the norm.

Any event architecture has to solve at least three problems:

  • Publication How do I find out what events there are?
  • Subscription How do I tell the system that I am interested in an event?
  • Delivery How does the event get delivered to me?

Event Publication

In WMI an event is published by declaring an event class. The occurrence of an event is represented by an instance of the class. All event classes are derived from the __Event system class.

NOTE
You can find the __Event class in CIM Studio under __SystemClass\__IndicationRelated. The leading double underscore for system classes is a naming convention used to keep the system class names separate from other class names. WMI does not allow you to declare a class with a leading underscore in the name.

The most important event classes defined by WMI are __InstanceOperationEvent and its derived classes. They are actually very simple, as you can see from the following MOF code:

 class __InstanceOperationEvent : __Event {    object TargetInstance; }; class __InstanceCreationEvent : __InstanceOperationEvent { }; class __InstanceDeletionEvent : __InstanceOperationEvent { }; class __InstanceModificationEvent : __InstanceOperationEvent {    object PreviousInstance; }; 

The two object declarations define embedded objects. These objects trigger the event. For example, when a new process comes into existence, as represented by a new instance of the Win32_Process class, a new instance of the __InstanceCreationEvent class is produced with its TargetInstance property containing the new process as an embedded object.

In this way, WMI provides an event representing every possible creation, modification, or deletion of any object in the rest of the namespace. Of course, these events are received only when requested—in the simplest computer systems, if you asked for all possible __InstanceOperationEvents, you would receive literally hundreds of events a second. You would essentially be monitoring every instance of a thread, process, file, service, or other component of the system changing state.

Event Subscription

In WMI, a client application subscribes to an event by creating a query. Queries are a natural way to interact with a class. You tell WMI which event you are interested in by calling one of several APIs, passing in a query that defines the event. For example, the following Microsoft Visual Basic code detects when a new process has been started and displays the name of the process:

 Dim wbemService As SWbemServices Dim events As SWbemEventSource Dim singleEvent As SWbemObject Dim sQuery As String Set wbemServices = GetObject("winmgmts:{impersonationLevel=impersonate}") sQuery = "select * from __instancecreationevent within 10 " & _    "where targetinstance isa `Win32_Process'" Set events = wbemServices.ExecNotificationQuery(sQuery) Do     Set singleEvent = events.NextEvent     MsgBox singleEvent.TargetInstance.Name  Loop 

The first statement of the code opens WMI by getting a handle on the WinMgmt service. The second statement provides the subscription query. The third statement invokes the ExecNotificationQuery function provided by the service to execute the query. The events object returned by the ExecNotificationQuery call has a NextEvent method that allows you to wait for the events as they occur. As you will see when we discuss event delivery, this example is the simplest possible case of using a query to request an event. WMI supports very sophisticated event subscription and delivery mechanisms suitable to a wide range of management applications.

NOTE
You should note some other features about the preceding code example as well. It takes advantage of the WMI scripting convention that assumes root\CIMV2 is the default namespace. Also, it does not include any error handling or termination code.

Event Delivery

Now let's turn to event delivery. You have seen one basic event delivery mechanism supported by the scripting interface that allows you to write simple scripts that can capture and handle events. Realistically, if you are going to use events as a part of a management application, you will need to deal with them in an asynchronous manner. You will also need to filter the events so that you see only the events you are interested in.

WMI allows you to control the way an event is delivered both in terms of which event is delivered and which data gets delivered with the event. This control is afforded by the fact that subscriptions are expressed using queries. We have already seen one very simple subscription query that gets an event each time a process is started.

Let's consider a slightly more complex example. Assume you want to get only the name of the service each time a manually started service is stopped. Your first step is to find a property that defines the way a service is started. Take a look at the Win32_Service class definition in CIM Studio. You should see a property named StartMode. Right-click on the property, and select Property Qualifiers to see its qualifiers. The ValueMap qualifier contains information about the start mode and can be one of the following values: Boot, System, Auto, Manual, and Disabled. We can check the StartMode property to see if it is "Manual". The name of the service is given by the Name property, so your subscription query would be as follows:

 Select TargetInstance.Name  From __InstanceModificationEvent  Within 10  Where TargetInstance isa `Win32_Service' and     TargetInstance.StartMode = `Manual' and    TargetInstance.Started = FALSE and     PreviousInstance.Started = TRUE 

Notice that the query uses the PreviousInstance value to determine whether the service's start status has changed from true to false. Many aspects of a service can change, but in this case we are interested only in whether the service has stopped. The query uses the Within clause to define a polling interval to be used by the CIM Object Manager in detecting the occurrence of the event. Basically the object manager re-evaluates the event every 10 seconds.

You can write a permanent event subscriber that is registered with WMI in such a way that any time the event occurs, the subscriber is invoked and can take some action. In the example we just looked at, you could make sure that an operator is notified every time your service is stopped.

WMI comes with a variety of standard subscribers that you can use to build sophisticated event handlers. For example, WMI can make use of Microsoft Message Queue (MSMQ) to guarantee delivery of events. WMI has standard subscribers that can issue command-line calls that, for example, allow you to send an e-mail message when an event occurs.



Programming Server-Side Applications for Microsoft Windows 2000
Programming Server-Side Applications for Microsoft Windows 2000 (Microsoft Programming)
ISBN: 0735607532
EAN: 2147483647
Year: 2000
Pages: 126

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net