Although putting an entry in
the Application log may suffice, you might be required at times to also
send a notification when a problem is found and a process has been
terminated. In this last section we will implement the code necessary to
send an e-mail alert when a process is terminated.
Updating the Configuration.xml File
Listing 1 represents the changes required to our configuration file so that the code will send an administrative alert.
Listing 1. E-mail configuration elements.
<SmtpServer>smtpserver</SmtpServer>
<Subject>Test Subject</Subject>
<Message>Found Message</Message>
<Sender>Michael.E.Gernaey@test.com</Sender>
<Recipient>Michael.E.Gernaey@test.com</Recipient>
<SmtpPort>25</SmtpPort>
<MailEnabled>true</MailEnabled>
|
Updating the WMI Class
We have to update the WMI class to enable e-mail notifications. We will add the code shown in Listing 2 to our WMI class to reflect these changes. You can add them to any section of your WMI class.
Listing 2. WMI e-mail notification changes.
Private m_SmtpClient As New SMTP
Private m_MailEnabled As Boolean
Public Property MailEnabled() As Boolean
Get
Return m_MailEnabled
End Get
Set(ByVal value As Boolean)
m_MailEnabled = value
End Set
End Property
Public ReadOnly Property SmtpClient() As SMTP
Get
Return m_SmtpClient
End Get
End Property
|
As with the FileWorker class, these properties will be used to implement e-mail notifications in the WMI class.
Updating the WMIWorkerOptions Class
Now that we have the WMI changes made, we need to update the WMIWorkerOptions class to store the properties required to send the e-mail notification. Listing 3 shows the required changes. You will also notice that we need to update the <Copy> method to reflect these additional properties.
Listing 3. WMIWorkerOptions e-mail notification property changes.
Private m_MailDetail As New EmailDetail
Public Property EmailProperties() As EmailDetail
Get
Return m_MailDetail
End Get
Set(ByVal value As EmailDetail)
m_MailDetail = EmailDetail.Copy(value)
End Set
End Property
Public Shared Sub Copy(ByVal wwo1 As WMIWorkerOptions, _
ByVal wwo2 As WMIWorkerOptions)
wwo1.Query = wwo2.Query
wwo1.Server = wwo2.Server
wwo1.WMIRoot = wwo2.WMIRoot
wwo1.EmailProperties.Message = wwo2.EmailProperties.Message
wwo1.EmailProperties.Recipient = wwo2.EmailProperties.Recipient
wwo1.EmailProperties.Sender = wwo2.EmailProperties.Sender
wwo1.EmailProperties.SmtpPort = wwo2.EmailProperties.SmtpPort
wwo1.EmailProperties.SmtpServer = wwo2.EmailProperties.SmtpServer
wwo1.EmailProperties.Subject = wwo2.EmailProperties.Subject
End Sub
|
The changes shown in Listing 3 reflect not only the implementation of the e-mail properties, but also the initialization of the e-mail properties in our <Copy> method.
Updating the <Tutorials.ThreadFunc> Method
Now that we have our new configuration elements and a place to store the properties in the WMIWorkerOptions class, we need to implement the changes required to read and assign these values. This will happen in our <ThreadFunc> method, as shown in Listing 4.
Listing 4. <ThreadFunc> e-mail notification changes.
If (Not tmpOptions Is Nothing) Then
Dim WWOptions As New WMIWorkerOptions
Dim children As System.Xml.XPath.XPathNavigator
Do
Try
children = tmpOptions.SelectSingleNode("Query")
WWOptions.Query = children.Value
children = tmpOptions.SelectSingleNode("Server")
WWOptions.Server = children.Value
children = tmpOptions.SelectSingleNode("WMIRoot")
WWOptions.WMIRoot = children.Value
children = tmpOptions.SelectSingleNode("Process")
WWOptions.Process = children.Value
Dim tmpDetail As New EmailDetail
children = tmpOptions.SelectSingleNode("Message")
tmpDetail.Message = children.Value
children = tmpOptions.SelectSingleNode("Subject")
tmpDetail.Subject = children.Value
children = tmpOptions.SelectSingleNode("Sender")
tmpDetail.Sender = children.Value
children = tmpOptions.SelectSingleNode("Recipient")
tmpDetail.Recipient = children.Value
children = tmpOptions.SelectSingleNode("SmtpPort")
tmpDetail.SmtpPort = children.Value
children = tmpOptions.SelectSingleNode("SmtpServer")
tmpDetail.SmtpServer = children.Value
WWOptions.EmailProperties = tmpDetail
Dim tmpWW As New WMI(m_ThreadAction, WWOptions)
children = tmpOptions.SelectSingleNode("MailEnabled")
tmpWW.MailEnabled = Convert.ToBoolean(children.Value)
m_WorkerThreads.Add(tmpWW)
tmpWW.Start()
Catch ex As Exception
WriteLogEvent(ex.ToString(), CONFIG_READ_ERROR,
EventLogEntryType.Error, My.Resources.Source)
End Try
Loop While (tmpOptions.MoveToNext)
End If
End If
|
The code in Listing 8-19 reads the values of our e-mail properties from the configuration file and then populates the EmailDetail property of our WMIWorkerOptions
class instance for each monitored process. Then it enables or disables
e-mail notifications based on the Mail-Enabled element in our
configuration file.
Updating the <WMI.ProcessWMIRequest> Method
Now we need to update the worker thread to send the e-mail notification when we terminate a process. Listing 5 shows these updates.
Listing 5. <ProcessWMIRequest> e-mail notification code.
'terminate the process
If Name.Trim = "Notepad.exe" Then
pMO.InvokeMethod("Terminate", Nothing)
If (Me.MailEnabled) Then
' Send the Email and then move it again to the processed Folder
m_WMIWorkerOptions.EmailProperties.Message = pszOut
m_SmtpClient.QueueMail(m_WMIWorkerOptions.EmailProperties)
End If
End If
|
The code in Listing 5
will validate that we have terminated a process and then place an
e-mail notification in our SMTP mail queue. When the mail queue has been
processed, the administrator or mail recipient will receive the
notification.
Service Validation
When the code is
installed and started, make sure that you create instances of the
process that you want to not only terminate, but also receive
notifications for. After the process has been terminated, you should see
an Application log entry and also receive an e-mail notification about
the termination.