newbie messing around with windows services & threads

dotolee

Member
Joined
Nov 30, 2004
Messages
20
Programming Experience
10+
Hi there.
i'm trying to create a windows service that:
1. monitors 3 other windows services.
2. sends an email if any of the 3 services stop / die.
I have two problems:
1. I dunno which event to use to code my main logic. THe main logic is pretty simple:
For each service I'm watching, I do something like:

ArcIMSMonitorWatchman.WaitForStatus(ServiceControllerStatus.Stopped)
SendStatusMessage("ArcIMS Monitor Service")

I tried putting this in the onstart event, but that didn't work out too good.
Do I use a timer?
2. My second problem is that someone suggested that I have to use threads to monitor three different services.
I've never created a multithreaded application before. Needless to say, now that I've added threading logic and the timer, the service doesn't work. No compile errors but no email is sent when I stop any / all of the monitored services.
I've included my code below
Please and thanks!

VB.NET:
[SIZE=1][SIZE=1][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=1] components [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1] System.ComponentModel.IContainer
[/SIZE][SIZE=1][COLOR=#008000]' NOTE: The following procedure is required by the Component Designer
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]' It can be modified using the Component Designer. 
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]' Do not modify it using the code editor.
[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Friend[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]WithEvents[/COLOR][/SIZE][SIZE=1] ArcIMSAppServerWatchman [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1] System.ServiceProcess.ServiceController
[/SIZE][SIZE=1][COLOR=#0000ff]Friend[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]WithEvents[/COLOR][/SIZE][SIZE=1] ArcIMSMonitorWatchman [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1] System.ServiceProcess.ServiceController
[/SIZE][SIZE=1][COLOR=#0000ff]Friend[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]WithEvents[/COLOR][/SIZE][SIZE=1] ArcIMSTaskerWatchman [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1] System.ServiceProcess.ServiceController
[/SIZE][SIZE=1][COLOR=#0000ff]Friend[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]WithEvents[/COLOR][/SIZE][SIZE=1] Timer1 [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1] System.Timers.Timer
[/SIZE][SIZE=1][COLOR=#008000]'2005.12.23 START Define thread variables
[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=1] thrAppServer [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=1] System.Threading.Thread([/SIZE][SIZE=1][COLOR=#0000ff]AddressOf[/COLOR][/SIZE][SIZE=1] MonitorESRIAppServer)
[/SIZE][SIZE=1][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=1] thrMonitor [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=1] System.Threading.Thread([/SIZE][SIZE=1][COLOR=#0000ff]AddressOf[/COLOR][/SIZE][SIZE=1] MonitorESRIAppServer)
[/SIZE][SIZE=1][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=1] thrTasker [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=1] System.Threading.Thread([/SIZE][SIZE=1][COLOR=#0000ff]AddressOf[/COLOR][/SIZE][SIZE=1] MonitorESRIAppServer)
[/SIZE][SIZE=1][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=1] bthreadstarted [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Boolean
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]'2005.12.23 STOP

[/COLOR][/SIZE][SIZE=1]<System.Diagnostics.DebuggerStepThrough()> [/SIZE][SIZE=1][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=1] InitializeComponent()[/SIZE][INDENT][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].ArcIMSAppServerWatchman = [/SIZE][SIZE=1][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=1] System.ServiceProcess.ServiceController
[/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].ArcIMSMonitorWatchman = [/SIZE][SIZE=1][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=1] System.ServiceProcess.ServiceController
[/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].ArcIMSTaskerWatchman = [/SIZE][SIZE=1][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=1] System.ServiceProcess.ServiceController
[/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].Timer1 = [/SIZE][SIZE=1][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=1] System.Timers.Timer
[/SIZE][SIZE=1][COLOR=#0000ff]CType[/COLOR][/SIZE][SIZE=1]([/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].Timer1, System.ComponentModel.ISupportInitialize).BeginInit()
[/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].Timer1.Interval = 3000
[/SIZE][SIZE=1][COLOR=#008000]'
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]'ArcIMSAppServerWatchman
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]'
[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].ArcIMSAppServerWatchman.ServiceName = "ArcIMS Application Server 4.0.1"
[/SIZE][SIZE=1][COLOR=#008000]'
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]'ArcIMSMonitorWatchman
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]'
[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].ArcIMSMonitorWatchman.ServiceName = "ArcIMS Monitor 4.0.1"
[/SIZE][SIZE=1][COLOR=#008000]'
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]'ArcIMSTaskerWatchman
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]'
[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].ArcIMSTaskerWatchman.ServiceName = "ArcIMS Tasker 4.0.1"
[/SIZE][SIZE=1][COLOR=#008000]'
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]'Timer1
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]'
[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].Timer1.Enabled = [/SIZE][SIZE=1][COLOR=#0000ff]True
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]'
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]'ESRIWatchman
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]'
[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].CanHandlePowerEvent = [/SIZE][SIZE=1][COLOR=#0000ff]True
[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].CanPauseAndContinue = [/SIZE][SIZE=1][COLOR=#0000ff]True
[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].ServiceName = "ESRIWatchman"
[/SIZE][SIZE=1][COLOR=#0000ff]CType[/COLOR][/SIZE][SIZE=1]([/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].Timer1, System.ComponentModel.ISupportInitialize).EndInit()
[/SIZE]
[/INDENT][SIZE=1][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Sub
[/COLOR][/SIZE][SIZE=1]#[/SIZE][SIZE=1][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Region

[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Protected[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Overrides[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=1] OnStart([/SIZE][SIZE=1][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=1] args() [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]String[/COLOR][/SIZE][SIZE=1])[/SIZE][INDENT][SIZE=1][COLOR=#008000]' Add code here to start your service. This method should set things
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]' in motion so your service can do its work.
[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].Timer1.Enabled = [/SIZE][SIZE=1][COLOR=#0000ff]True
[/COLOR][/SIZE]
[/INDENT][SIZE=1][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Sub

[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Protected[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Overrides[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=1] OnStop()[/SIZE][INDENT][SIZE=1][COLOR=#008000]' Add code here to perform any tear-down necessary to stop your service.
[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=1].Timer1.Enabled = [/SIZE][SIZE=1][COLOR=#0000ff]False
[/COLOR][/SIZE]
[/INDENT][SIZE=1][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Sub
[/COLOR][/SIZE][SIZE=1][COLOR=#008000]'Private Function SendStatusMessage() As Boolean

[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Function[/COLOR][/SIZE][SIZE=1] SendStatusMessage([/SIZE][SIZE=1][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=1] strserviceName [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]String[/COLOR][/SIZE][SIZE=1]) [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Boolean[/COLOR][/SIZE][INDENT][SIZE=1][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=1] objSMTP [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1] System.Web.Mail.SmtpMail
[/SIZE][SIZE=1][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=1] Mailmsg [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=1] System.Web.Mail.MailMessage
[/SIZE][SIZE=1][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=1] strEmailMessage [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]String
[/COLOR][/SIZE][SIZE=1]objSMTP.SmtpServer = "exowa.vgn.cty"
Mailmsg.To = "julie.woo@vaughan.ca"
Mailmsg.From = "ESRIWatchman@vaughan.com"
Mailmsg.BodyFormat = MailFormat.Html [/SIZE][SIZE=1][COLOR=#008000]'Send the mail in HTML Format
[/COLOR][/SIZE][SIZE=1]Mailmsg.Subject = "ArcIMS Service Failure Notification"
strEmailMessage = "<BODY bgcolor='#FFFFFF' text='#000000' link='#0033CC' vlink='#660066' alink='#00CC33'>"
strEmailMessage = strEmailMessage & "<table align='center' border='1' style='background-color: beige; width:50%; border-width: 1px; padding: 0px;' cellspacing='0'>"
strEmailMessage = strEmailMessage & "<tr><td><B>ESRI Watchman - Service Status<p></B></TD></TR>"
strEmailMessage = strEmailMessage & "<tr><td>"
strEmailMessage = strEmailMessage & "<table align='center' style='background-color: #EFEFEF; width: 99%;' cellspacing='3' border='0'>"
[/SIZE][SIZE=1][COLOR=#0000ff]Select[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Case[/COLOR][/SIZE][SIZE=1] UCase(strserviceName)
[/SIZE][SIZE=1][COLOR=#0000ff]Case[/COLOR][/SIZE][SIZE=1] "ARCIMS APPLICATION SERVER SERVICE"
strEmailMessage = strEmailMessage & "<tr><td>ArcIMS Application Server Service Status: " & ArcIMSAppServerWatchman.Status.ToString & "</td></tr>"
[/SIZE][SIZE=1][COLOR=#0000ff]Case[/COLOR][/SIZE][SIZE=1] "ARCIMS MONITOR SERVICE"
strEmailMessage = strEmailMessage & "<tr><td>ArcIMS Monitor Service Status: " & ArcIMSMonitorWatchman.Status.ToString & "</td></tr>"
[/SIZE][SIZE=1][COLOR=#0000ff]Case[/COLOR][/SIZE][SIZE=1] "ARCIMS TASKER SERVICE"
strEmailMessage = strEmailMessage & "<tr><td>ArcIMS Tasker Service Status: " & ArcIMSTaskerWatchman.Status.ToString & "</td></tr>"
[/SIZE][SIZE=1][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Select
[/COLOR][/SIZE][SIZE=1]strEmailMessage = strEmailMessage & "</table></td></tr></table>"
Mailmsg.Body() = strEmailMessage
objSMTP.Send(Mailmsg)
[/SIZE][SIZE=1][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Function
[/COLOR][/SIZE]
[/INDENT][SIZE=1][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=1] MonitorESRIAppServer()[INDENT]ArcIMSAppServerWatchman.WaitForStatus(ServiceControllerStatus.Stopped)
SendStatusMessage("ArcIMS Application Server Service")

[/INDENT][/SIZE][SIZE=1][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Sub

[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=1] MonitorESRIMonitor()[INDENT]ArcIMSMonitorWatchman.WaitForStatus(ServiceControllerStatus.Stopped)
SendStatusMessage("ArcIMS Monitor Service")

[/INDENT][/SIZE][SIZE=1][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Sub

[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=1] MonitorESRITasker()[INDENT]ArcIMSTaskerWatchman.WaitForStatus(ServiceControllerStatus.Stopped)
SendStatusMessage("ArcIMS Tasker Service")

[/INDENT][/SIZE][SIZE=1][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Sub

[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=1] Timer1_Elapsed([/SIZE][SIZE=1][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=1] sender [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1] System.Object, [/SIZE][SIZE=1][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=1] e [/SIZE][SIZE=1][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=1] System.Timers.ElapsedEventArgs) [/SIZE][SIZE=1][COLOR=#0000ff]Handles[/COLOR][/SIZE][SIZE=1] Timer1.Elapsed[/SIZE][INDENT][SIZE=1][COLOR=#0000ff]If[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Not[/COLOR][/SIZE][SIZE=1] bthreadstarted [/SIZE][SIZE=1][COLOR=#0000ff]Then[/COLOR][/SIZE][INDENT][SIZE=1]bthreadstarted = [/SIZE][SIZE=1][COLOR=#0000ff]True
[/COLOR][/SIZE][SIZE=1]thrAppServer.Start()
thrMonitor.Start()
thrTasker.Start()
[/SIZE]
[/INDENT][SIZE=1][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]If
[/COLOR][/SIZE]
[/INDENT][SIZE=1][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=1][COLOR=#0000ff]Sub[/COLOR][/SIZE][/SIZE]

 
Last edited by a moderator:
Forget the extra threads. All you need to do is check the Status property of each ServiceController. You would create a method that checks each Status and sends e-mails, starts services or whatever, then call that method from your service's OnStart method and the Tick event handler of your Timer.
 
Ok. So I removed the threads to make things less complicated.
However, there is still a bug where the custom service doesn't seem to notice a refresh on the status of the three 3 monitored services. EG) If I stop one of the three services, let the timer elapse, get notification and then restart service, my custom service will continue to send a notification ...
My timer interval is 12000.

Me.Timer1.Interval = 12000

Any ideas? My timer elapsed event handler looks like this:

Private Sub Timer1_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed
'Check Status

With ArcIMSAppServerWatchman
WriteToEventLog("ArcIMSAppServerWatchman " & .Status)
If (.Status = ServiceControllerStatus.Paused) Or (.Status = ServiceControllerStatus.Stopped) Then
WriteToEventLog("ARCIMS Application Server Down")
SendStatusMessage("ARCIMS APPLICATION SERVER SERVICE")
End If
End With

With ArcIMSMonitorWatchman
WriteToEventLog("ArcIMSMonitorWatchman " & .Status)
If (.Status = ServiceControllerStatus.Paused) Or (.Status = ServiceControllerStatus.Stopped) Then
WriteToEventLog("ARCIMS Application Server Down")
SendStatusMessage("ARCIMS MONITOR SERVICE")
End If
End With

With ArcIMSTaskerWatchman
WriteToEventLog("ArcIMSTaskerWatchman " & .Status)
If (.Status = ServiceControllerStatus.Paused) Or (.Status = ServiceControllerStatus.Stopped) Then
WriteToEventLog("ARCIMS Application Server Down")
SendStatusMessage("ARCIMS TASKER SERVICE")
End If
End With

End Sub
 
Last edited:
Calling a .refresh method on the service controller before checking status. seems to be fine now.
DOH!
Thanks anyways.
 
Back
Top