Notification plugin Programmer’s guide, What’s GOLD
Sunday, April 5th, 2009
Notification plugin Programmer's guide
This section will go through the necessary steps to create a notification plug-in for WhatsUp Gold v6.0 using Visual C++ v6.0. The sample plug-in created by this tutorial will be a SysLog notification plug-in. The completed version of this plug-in can be found in the Samples directory that was created during the installation process.
Step 1 – Creating a new ATL project
Create a new ‘ATL COM AppWizard’ project named ‘SysLogPlugInSample’
Select ServerType – DLL
Check the box to allow merging of proxy/stub code
Click Finish
This step created the SysLogPlugInSample.cpp/.h/.def/.idl/.rc files.
Step 2 – Creating the new ATL COM object
Insert a new ATL object using the menu commands, Insert->New ATL Object...
Select Simple Object
Click Next
Type ‘SysLogSample’ in the ShortName field
Click on the Attributes tab
Select ‘Apartment’ threading model
Select ‘Custom’ interface
Click OK
This step has created the SysLog.cpp/.h files and entered some information in the SysLogPlugInSample.idl file.
Step 3 – Defining the required interfaces
By creating the new ATL Simple Object, it has setup some defaults for us. We now need to change the defaults and define the required interfaces.
Open the SysLogPlugInSample.idl file in the Visual Studio editor
Remove the block that defines the ISysLogSample interface. It will look something like this:
[
object,
uuid(C89F80D1-B3F1-11D4-804A-0001025EB176),
helpstring("ISysLogSample Interface"),
pointer_default(unique)
]
interface ISysLogSample : IUnknown
{
};
After this block is removed, scroll to the bottom of the file and look for the following block:
coclass SysLogSample
{
[default] interface ISysLog;
};
Change ‘interface ISysLogSample’ to ‘interface IUnknown’
Next, copy the following block under the import section and before the SysLogPlugInSample library section.
[
uuid(5512E7A0-8B31-11d4-803D-0001025EB176)
]
interface IWUGNotification : IUnknown
{
[helpstring("method Initialize")] HRESULT Initialize(IUnknown* pWUGUnk);
[helpstring("method UnInitialize")] HRESULT UnInitialize();
[helpstring("method Notify")] HRESULT Notify([in]BSTR bstrNotificationPathName);
};
[
uuid(5512E7A1-8B31-11d4-803D-0001025EB176)
]
interface IWUGNotificationInstanceEditor : IUnknown
{
[helpstring("method AddInstance")] HRESULT AddInstance([in]BSTR bstrInstancePath, [out]BSTR* pbstrName);
[helpstring("method EditInstance")] HRESULT EditInstance([in]BSTR bstrInstancePath, [in, out]BSTR* bstrInstanceName);
[helpstring("method GetIconInfo")] HRESULT GetIconInfo([out]long* pHINSTANCE, [out]long* pID);
};
[
uuid(8658B6A0-9869-11d4-8044-0001025EB176)
]
interface IWUGWebNotificationInstanceEditor : IUnknown
{
[helpstring("method GetWebAddInstancePage")] HRESULT GetWebAddInstancePage([in]BSTR bstrInstancePath, [out]BSTR* pbstrPage);
[helpstring("method GetWebEditInstancePage")] HRESULT GetWebEditInstancePage([in]BSTR bstrInstancePathName, [out]BSTR* pbstrPage);
[helpstring("method UpdateWebInstancePage")] HRESULT UpdateWebInstancePage([in]BSTR bstrPathName, [in]BSTR bstrPage);
};
Step 4 – Provide a default implementation for the required interfaces
Open SysLogSample.h in the editor
Remove ‘public ISysLogSample’ in the CSysLogSample inheritence list
Add the following block to the inheritence list:
public IWUGNotification,
public IWUGNotificationInstanceEditor
Remove the ‘COM_INTERFACE_ENTRY(ISysLogSample)’ within the BEGIN_COM_MAP(CSysLogSample) section.
Add the following block in the BEGIN_COM_MAP(CSysLogSample) section:
COM_INTERFACE_ENTRY(IWUGNotification)
COM_INTERFACE_ENTRY(IWUGNotificationInstanceEditor)
Now add the following block under the END_COM_MAP() line in the header:
// IWUGNotification methods
STDMETHOD(Initialize)(IUnknown* pWUGUnk);
STDMETHOD(UnInitialize)();
STDMETHOD(Notify)(BSTR bstrNotificationPathName);
// IWUGNotificationInstanceEditor methods
STDMETHOD(AddInstance)(BSTR bstrInstancePath, BSTR* pbstrName);
STDMETHOD(EditInstance)(BSTR bstrInstancePath, BSTR* pbstrInstanceName);
STDMETHOD(GetIconInfo)(/*[out]*/long* pHINSTANCE, /*[out]*/long* pID);
Open SysLog.cpp in the editor
Copy the following block into the file:
// IWUGNotification methods
STDMETHODIMP CSysLogSample::Initialize(IUnknown* pWUGUnk)
{
return E_NOTIMPL;
}
STDMETHODIMP CSysLogSample::UnInitialize()
{
return E_NOTIMPL;
}
STDMETHODIMP CSysLogSample::Notify(BSTR bstrNotificationPathName)
{
return E_NOTIMPL;
}
// IWUGNotificationInstanceEditor
STDMETHODIMP CSysLogSample::AddInstance(BSTR bstrNotificationPathName, BSTR* pbstrName)
{
return E_NOTIMPL;
}
STDMETHODIMP CSysLogSample::EditInstance(BSTR bstrNotificationPath, BSTR* pbstrInstanceName)
{
return E_NOTIMPL;
}
STDMETHODIMP CSysLogSample::GetIconInfo(long* pHINSTANCE, long* pID)
{
return E_NOTIMPL;
}
Save all files and compile – the compile should build SysLogPlugInSample.dll with no errors
Step 6 – Register the plug-in with WhatsUp Gold
The steps in this section write the registry entries for WhatsUp Gold to recognize the notification plug-in.
Open SysLogPlugInSample.cpp in the editor
Find the DllRegisterServer function and add the following block of code at the top of the function:
HKEY hKey;
LONG lErr;
lErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SoftwareIpswitchWhatsUpNotification", 0, KEY_WRITE, &hKey);
if (lErr == ERROR_SUCCESS)
{
HKEY hMyKey;
lErr = RegCreateKey(hKey, "SysLog", &hMyKey);
if (lErr == ERROR_SUCCESS)
{
char* pszCLSID = "{C89F80D2-B3F1-11D4-804A-0001025EB176}";
char* pszDesc = "SysLog notification component";
char* pszDisplayName = "SysLog";
char* pszManufacturer = "Ipswitch, Inc.";
RegSetValueEx(hMyKey, "CLSID", 0, REG_SZ, (const BYTE*)pszCLSID, lstrlen(pszCLSID));
RegSetValueEx(hMyKey, "Desc", 0, REG_SZ, (const BYTE*)pszDesc, lstrlen(pszDesc));
RegSetValueEx(hMyKey, "DisplayName", 0, REG_SZ, (const BYTE*)pszDisplayName, lstrlen(pszDisplayName));
RegSetValueEx(hMyKey, "Manufacturer", 0, REG_SZ, (const BYTE*)pszManufacturer, lstrlen(pszManufacturer));
RegCloseKey(hMyKey);
}
RegCloseKey(hKey);
}
Find the DllUnregisterServer function and add the following block of code to the top of the function:
HKEY hKey;
LONG lErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SoftwareIpswitchWhatsUpNotification", 0, KEY_WRITE, &hKey);
if (lErr == ERROR_SUCCESS)
{
RegDeleteKey(hKey, "SysLog");
RegCloseKey(hKey);
}
Step 7 – Creating the persistence methods
Steps 7 and above provide the actual implementation of the SysLog plug-in. Not all of the code is available in this document. If you wish to view the full implementation of this plug-in, refer to the Samples directory.
Open SysLog.h
Add the following public methods:
bool SaveInstance(LPCSTR pszPathName, int nPort, LPCSTR pszAddress, LPCSTR pszMessage);
bool LoadInstance(LPCSTR pszPathName, int& nPort, LPSTR pszAddress, LPSTR pszMessage);
Implement the Save and Load methods in SysLog.cpp. These methods will be used to serialize the notification instance data to and from disk. In our implementation of these methods, we are using a GUID to determine the validity & version of the instance file. This GUID was created with the GUIDGEN tool available in Visual Studio.
Step 8 – Creating the user interface object(s)
Insert an ATL Dialog into the project (Insert->ATL Object…, Miscellaneous category, select dialog)
Enter ‘SysLogInstanceDlg’ in the Short Name field
Click Ok
Create controls for the InstanceName, Port, HostAddress, and Message
Open SysLogInstanceDlg.h and SysLogInstanceDlg.cpp in the editor
Edit code – change the CSysLogInstanceDlg constructor to pass a pointer to the CSysLogSample class, the instance path, and an instancename (default NULL). This allows the dialog class to handle both Add and Edit scenarios.
Edit code in the OnInitDialog method to determine whether it’s an add or delete operation, and fill up the fields accordingly.
Edit code in the OnOk method to validate the data fields and call CSysLogSample::SaveInstance (the pointer to the CSysLogSample object was passed in the constructor) to save the data.
Create an ICON resource via the Resource Editor. Name it syslog.ico and set the resource ID to IDI_SYSLOG_ICON
Modify the IWUGNotificationInstanceEditor::GetIconInfo method (in SysLog.cpp) to return the instance handle and the resource id (IDI_SYSLOG_ICON).
Step 9 – Code the real implementation of the required interfaces
This step starts implementing the required interfaces for the plug-in. An answer for this step can be found in the Samples/SysLogPlugInSample/SysLog.cpp file. Make sure to look for the m_pWUGHelper member. This member is a IWUGNotificationHelper interface pointer (this interface definition can be found in the WUGNotificationInterfaces.h file). This code uses this pointer to add entries to the debug log, and to format the text that will be sent to the syslogger.
Modify the project to include ws2_32.lib (in the link – object/library modules line)
Modify the project to enable exception handling (in the C/C++ tab, C++ Language category, click on the Enable Exception Handling checkbox)
Add members for the IWUGNotificationHelper interface pointer, a socket, etc.
Modify the CSysLogSample constructor to initialize all member variables.
Add a destructor to the class – make the destructor call UnInitialize(). This will make sure that everything is properly release when the plug-in is unloaded.
Implement code for the IWUGNotification interface methods:
o Initialize – Initialize the Winsock library, create a udp socket, and save the IWUGNotificationHelper interface
o UnInitialize – Release the IWUGNotificationHelper interface, close the udp socket, cleanup the Winsock library
o Notify – Read the instance data, format the data, send the data to the specified address
Implement the AddInstance & EditInstance methods of the IWUGNotificationInstanceEditor interface. These methods should invoke the SysLogInstanceDlg to display the UI, allow the user to enter data, and save the notification instance.
Step 10 – Test the plug-in
The compiler should have been registering the component after every build, if not, use regsvr32.exe to register the component with COM (and with WhatsUp Gold, since we put the initialization in the DllRegisterServer, it will be called when the component is registered).
Start WhatsUp Gold and verify that the SysLog component is available in the Notification Library dialog.
Create a new instance of the SysLog notification called ‘TestSysLog’, set the port to 514, the address to 127.0.0.1, and the message to ‘This is a test of the SysLog plug-in’.
Create a new map, add one device with the ip address of 128.0.0.2.
Assign an alert to the device – ‘TestSysLog’, trigger=1, 24x7
Open the SysLog log viewer (Logs->SysLog logs…)
Wait for the map to poll, wait a few seconds and refresh the SysLog log viewer. The message that we saved in the ‘TestSysLog’ instance should be displayed in the log viewer.
Step 11 – Add Web Support
Open Syslog.h in the editor
Add the following line of code to the inheritance list:
public IWUGWebNotificationInstanceEditor
Add the following line in the BEGIN_COM_MAP() section:
COM_INTERFACE_ENTRY(IWUGWebNotificationInstanceEditor)
Add the follow block of code to the CSysLogSample header
// IWUGWebNotificationInstanceEditor methods
STDMETHOD(GetWebAddInstancePage)(BSTR bstrInstancePath, BSTR* pbstrPage);
STDMETHOD(GetWebEditInstancePage)(BSTR bstrInstancePathName, BSTR* pbstrPage);
STDMETHOD(UpdateWebInstancePage)(BSTR bstrPathName, BSTR pbstrPage);
Add the following block of code to the CSysLogSample implementation file
STDMETHODIMP CSysLogSample::GetWebAddInstancePage(BSTR bstrInstancePath, BSTR* pbstrPage)
{
return E_NOTIMPL;
}
STDMETHODIMP CSysLogSample::GetWebEditInstancePage(BSTR bstrInstancePathName, BSTR* pbstrPage)
{
return E_NOTIMPL;
}
STDMETHODIMP CSysLogSample::UpdateWebInstancePage(BSTR bstrPathName, BSTR bstrPage)
{
return E_NOTIMPL;
}
Add code to return the web pages for the GetWebAdd/EditInstancePage methods
Add to process the values returned from the form in UpdateWebInstancePage
|
|
|
|
|
|
Plurk This Post
Ping This Post
Reddit
Stumble This Post
No related posts.
tagged under: notification plugin.programmers guide





Link to this page



