|
EventConsumer
This sample demonstrates a permanent event consumer. Events are
generated from the Advanced Client sample application by adding equipment. This
application shows how to implement a simple IWBEMUnboundObjectSink and its
class factory. You should generate your own CLSID when building your permanent
consumer.
Building the EventConsumer Sample
The application can be
built from the command line using NMAKE, or it can be built using Microsoft
Visual C++.
From the command line
in the sample installation directory:
NMAKE /f "Makefile"
From Microsoft Visual
C++:
1.
Select File + Open Workspace
2.
Select the PermEvents.dsp file
Registering the
Consumer
The SampleViewer.mof uses a special namespace and you must
therefore compile the SampleViewer.mof to create the namespace and register
this consumer before running the Client sample application.
From the command line in
the sample installation directory type the following:
MOFCOMP SampleViewer.mof
In order to explicitly
register the consumer with COM, you may specify the /RegServer command line
switch when running the executable. From the command line in the sample installation
directory type the following:
PermEvents.exe /RegServer
It should be noted,
however, that the executable would register itself automatically without
specifying this switch.
Common Event Consumer Tasks Demonstrated by the Sample
Functions
Task: Handle an event
Implementation:
Consumer.cpp is the actual handler. The IndicateToConsumer()
method will be called with the event instance embedded.
Task: Creating the
handler object
Implementation:
factory.cpp creates the sink object. It is a simple class factory.
Task: Registering the
object and factory
Implementation:
PermEvents.cpp registers the sink object with its class factory in
the InitInstance() routine. The registration is revoked in the ExitInstance().
Task: Self-registering
an EXE
Implementation:
PermEvents.cpp has the RegisterServer() and UnregisterServer()
routines to show self-registration of an EXE. It is not the same as a DLL. The
'AppID' and 'RunAs' values allow the spawned EXE to run on the user's desktop
instead of the service's hidden desktop. Otherwise the Event Consumer would
never appear.
Build Notes
Things
to remember when you're building your own WMI client application:
1.
If you want your client to
run on NT and non-DCOM versions of Windows 95, manually load the ole32.dll and
see if CoInitializeSecurity() exists. This routine won’t exist on Windows 95
installations that don’t have DCOM installed separately. If this routine
doesn't exist, the asynchronous routines in this sample won’t work because of
mismatched security level problems. The synchronous techniques will still work.
2.
If you don’t care about
non-DCOM versions of Windows 95, you can define _WIN32_DCOM so that CoInitializeSecurity() is available for
implicit linking. Don't use _WIN32_WINNT to get this prototype since it won't
compile under the Windows 95/98 operating systems.
3.
In any case, the
CoInitializeSecurity() call (in InitInstance()) is required to work around a
security problem when WMI trying to call a Sink object but won't identify
itself. The CoInitializeSecurity() call turns off the authentication
requirement.
4.
WMI interfaces are defined
in wbemcli.h and wbemprov.h found in the wmi\include directory. You may #include both these files by
including just wbemidl.h located in the same directory.
5.
WMI interface CLSIDs are
defined in wbemuuid.lib. If you get unresolved externals in interfaces and
CLSIDs, this is what is missing.
6.
You'll need to link with
oleaut32.lib and ole32.lib to get the needed COM support.
7.
In the Link|Output
settings, specify 'wWinMainCRTStartup' as the entry point. This is per the
Unicode programming instructions.
8.
If you're using the makefiles, don't forget to set the VC vars. In
VC++ 5.0, it is VCVARS32.BAT.