This section includes the following articles:
To create a new COM-based MSI client, follow these steps:
This application might be an executable (EXE) or a DLL, which is
designed to run in a surrogate process. Either way, your MSI Client
class must support the instantiation as a local server
(CLSCTX_LOCAL_SERVER
).
This figure shows an example project setup in Microsoft Visual Studio 2005. The Application is called "ComMsiApp." The build result is a COM executable.
In the example, this class is the "ComMsiClient" class.
IOvOWMsiClient.idl
and
OvOWExTypes.idl
in your project, so that it can be
processed by the MIDL tool.
Including these files will generate the type library as well as a header file and marshalling code.
import "oaidl.idl"; import "ocidl.idl"; import "OvOWMsiClient.idl"; //... // interface definition for your ComMsiClient [ uuid(52463E05-58AB-4D33-B675-E20D6CCA2F0D), version(1.0), helpstring("ComMsiApp 1.0 Type Library") ] library ComMsiAppLib { importlib("stdole2.tlb"); [ uuid(48A4B84E-9A15-43BC-8260-60152C2482EE), helpstring("ComMsiClient Class") ] coclass ComMsiClient { [default] interface IComMsiClient; interface IOvOWMsiCLient; }; }; |
// ComMsiClient.h : Declaration of the CComMsiClient #pragma once #include "resource.h" #include "ComMsiApp.h" // CComMsiClient class ATL_NO_VTABLE CComMsiClient : public CComObjectRootEx<CComMultiThreadModel>, public CComCoClass<CComMsiClient, &CLSID_ComMsiClient>, public ISupportErrorInfo, public IComMsiClient, public IOvOWMsiClient { //... }; |
In Microsoft Visual Studio 2005, you can reuse large parts of the wizard-generated code. You just need to implement the methods derived from IOvOWMsiClient. When the build succeeds, you are done with the basics.
You can find the MSI client example in the following directory:
%OvInstallDir%\examples\OVOW\DevelopmentKit\Server\MSI\CppCOM"
When working with MSI interfaces, you can do the following:
To connect to the MSI server, follow these steps:
To retrieve the MSI server in a method, you can use code such as the following.
STDMETHODIMP CComMsiClient::retrieveMsiServer(IOvOWMsiServer **ppMsiServer) { CComPtr<IOvOWMsiLocator> pMsiLocator; HRESULT hr = CoCreateInstance(CLSID_OvOWMsiLocator, NULL, CLSCTX_INPROC_SERVER, IID_IOvOWMsiLocator, reinterpret_cast<void **>(&pMsiLocator)); if (FAILED(hr)) { // maybe trace the hr; something went wrong return hr; } if (pMsiLocator == NULL) { return E_FAIL; } CComPtr<IOvOWMsiServer> pMsiServer; hr = pMsiLocator->connectToMsiServer(&pMsiServer); if (FAILED(hr)) { // MSI Locator returned an error return hr; } return pMsiServer.CopyTo(ppMsiServer); } |
You can also use easier and less cryptic ways of instantiating the MSI Locator. Instead of using the CLSID, you can use the ProgId. Instantiation with the ProgId works for all MSI components. For details, refer to the HPOM for Windows server-based MSI API documentation.
connectClient(...)
.
The following method shows what a generic
connectClient(...)
call might look like. You may have
fixed values (for example, for appName
,
readWriteMode
, and so on) and therefore no need for
all the arguments used in this example.
STDMETHODIMP CComMsiClient::connectClient(BSTR appName, int readWriteMode, IOvOWMsiServer **ppMsiServer, int *interfaceId) { HRESULT hr; if (m_pMsiServer == NULL) { m_pMsiServer.Release(); hr = this->retrieveMsiServer(&m_pMsiServer); if (FAILED(hr)) { return hr; } } hr = m_pMsiServer->connectClient(appName, this, readWriteMode, ppMsiServer, interfaceId); if (interfaceId != NULL) { m_interfaceId = *interfaceId; // remember the interfaceId for the later call to disconnectClient(...) } return hr; } |
The interfaceId
identifies the connection between
your MSI Client and the HPOM for Windows MSI server. You should
keep it if you want to call disconnectClient(...)
later.
For the exact definition of the MSI client connection modes, refer to the HPOM for Windows COM API documentation.
To set up a register condition, you can use code such as the following.
CComPtr<IOvOWRegisterCondition> regCond; hr = regCond.CoCreateInstance(CLSID_OvOWRegisterCondition); |
The register condition does not have any specifics, so it will
match all messages. To register for messages with critical severity
only, set the severity property to
OVEP_C_SEV_CRIT
.
hr = regCond->put_MessageSeverity(OVEP_C_SEV_CRIT); |
You can register the MSI client at the MSI server with the register condition you just prepared.
STDMETHODIMP CComMsiClient::registerClient(int interfaceId, IOvOWRegisterCondition *condition, int *conditionId) { if (m_pMsiServer == NULL) { return E_FAIL; } HRESULT hr = m_pMsiServer->registerClient(interfaceId, condition, conditionId); m_lastMsiAppEvents.registerClientCallReturn = hr; return hr; } |
The returned conditionId identifies this specific registration call. You can use it later to unregister the specific register condition. However, you need to connect to the MSI server before you can register for messages.
After you connect to the MSI server and register your MSI client to receive messages, your client will receive messages sooner or later. For testing, you can use the opcmsg command-line tool to generate HPOM messages that match at least one of your registrations.
When your MSI client is eligible to receive a message, the MSI
server calls the receiveMessage(...)
method of your
MSI client. The argument is the message.
You can now read the properties of the message and, as an example, store them in a file. If the message was diverted to your MSI client, you can also decide not to reinsert it into the MSI server. In that case, the message will not reach the HPOM for Windows Message Server Database, and it will not display in the HPOM for Windows Message Browser.
In the following code sample, an HPOM Message is received and reinserted into the MSI server without any processing.
STDMETHODIMP CComMsiClient::receiveMessage(IOvOWServerMessage *message) { // you can do anything with the Message (for example, read the Message Text property) CComBSTR msgText; message->get_Text(&msgText); // now return the Message to the MSI Server if (m_pMsiServer == NULL) { return E_FAIL; } HRESULT hr = m_pMsiServer->insertMessage(m_interfaceId, message); if (FAILED(hr)) { // maybe trace the hr; something went wrong return hr; } return S_OK; } |
If the MSI Client has connected to the MSI Server with the appropriate MSI Client Connection Mode, you can also add new message to the HPOM for Windows message server.
The following code samples shows a method that creates a message with normal severity and the specified Message Text, and inserts it into the HPOM for Windows message server.
STDMETHODIMP CComMsiClient::feedNormalMessage(BSTR messageText) { if (m_pMsiServer == NULL) { return E_FAIL; } if (messageText == NULL) { return E_INVALIDARG; } CComPtr pNewMessage; HRESULT hr = CoCreateInstance(CLSID_OvOWServerMessage, NULL, CLSCTX_ALL, IID_IOvOWServerMessage, reinterpret_cast<void **>(&pNewMessage)); if (FAILED(hr)) { // Check for hr; something went wrong return hr; } pNewMessage->put_Text(messageText); pNewMessage->put_Severity(OVEP_C_SEV_NORMAL); return m_pMsiServer->insertMessage(m_interfaceId, pNewMessage); } |
If you have stored the ID of the register condition you want to
remove, and if m_pMsiServer
is not NULL
,
you can remove the register condition by calling the following.
HRESULT hr = m_pMsiServer->unregisterClient(conditionId); |
You can remove all Registrations of your MSI client by calling the following.
HRESULT hr = m_pMsiServer->removeAllRegistrations(interfaceId); |
In this example, the interface ID is used because it is easier than remembering all condition IDs.
You can disconnect an MSI client from the MSI server by calling the following.
HRESULT hr = m_pMsiServer->disconnectClient(interfaceId); |
This call also causes the removal of all registrations made by
this MSI client during the last connection. Expect the
serverShutdown(...)
method to be called instantly by
the MSI server.
For calls to serverInit()
or
serverShutdown()
, do the following:
Call to serverInit()
signals that the HPOM for
Windows MSI server is running and (based on your connection mode)
ready to stream HPOM messages to the MSI client, receive messages
from the MSI client, or both. It is usually called when the MSI
client connects to the MSI server successfully.
Call to serverShutdown()
signals the disconnect of
the MSI client. This may result from either a direct call to
disconnectClient(...)
or the shutdown of the entire
HPOM for Windows MSI server (for example, during a shutdown or a
restart of the HPOM for Windows Message server). It is recommended
that you perform any necessary MSI connection-specific cleanup.
Most likely, the next method called in the MSI client will be
FinalRelease()
, which indicates the destruction of the
MSI client process.
Since HP Operations Manager for Windows 8.10, the Message/Action Server, which hosts the MSI server, runs under a non-admin user account. You must configure MSI COM clients for DCOM access to allow instantiation and communication between server and client.
To configure MSI COM clients for DCOM access, follow these steps:
dcomcnfg
:
dcomcnfg
.Component Services
Computers
DCOM Config
My Computer
The application name is typically the prefix of your COM client
Prog ID. For example, if your client ProgID is
MyComApp.MyComClient
, you most likely find the entry
MyComApp
in the list.
OvEpMsgActSrv.exe
process is running to the list of
users.
By installation default, the user account is
HP-OVE-User
. If you chose a different user name during
installation, add this user to the list instead. If in doubt, open
the Task Manager from the Task Bar, and check the User Name entry
for the process.
Note that the Deny fields remain unselected.
If you get further errors about insufficient access rights, add
Access Permissions for HP-OVE-User
(or the user name
you chose) to your COM application.
It is up to you to chose any trace tool you prefer to instrument your COM MSI Application. The performance of the HPOM for Windows MSI Server will not be affected.
Tracing is generally useful to see what your application is doing and can be helpful to find bugs in early development phases.
To display trace messages of the MSI server, you need to use the built-in trace client of HPOM.
To enable trace messages, follow these steps:
<InstallDir>\support\ovtrcadm.exe -a
localhost
, where <InstallDir>
is your
HPOM Installation Directory.<InstallDir>\support\ovtrcgui.exe
.
The Trace Client GUI appears.
OvOWMsi
.A list view appears.
New MSI Server traces are shown in the list view. Use Edit→Options to configure which attributes should be displayed.
To close the Trace Client GUI, follow these steps: