Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  .NET Newbie  »  Windows Services for VB.NET Developers  »  Coding the body
 »  Home  »  Windows Development  »  Windows Services for VB.NET Developers  »  Coding the body
Windows Services for VB.NET Developers
by Scott Rutherford | Published  12/20/2005 | .NET Newbie Windows Development | Rating:
Coding the body

We are now ready to add programming to the service to make it do something.

    The Service Class (Code-behind)

    The Service class (e.g. EmptyService) will receive the Start and Stop commands for the service and must therefore implement OnStart() and OnStop(), which both override methods in the base ServiceProcess class. When you implement the more simple Service, with a Timer control, you would set the Enabled property of the Timer to True in OnStart() and set it to False in OnStop(). For our example, we will use these start/stop event handlers to create and destroy threads which will run the meat of our program.

    The next section of the article will discuss the contents of the Worker class. For now, we will create a private member of the Service class of type Worker. This is a singleton object that attaches to the main running program thread and performs work. In the OnStart() event handler, a new thread is created, with its start-point set to the Worker object’s main method (called “DoWork()”). Then the thread is started. In the OnStop() event handler, the worker object is torn down by first calling its StopWork() method and then freeing any extra objects used by the service.

    Windows Service processes are started by the SCM, and hence their working directory is that of the system, by default. An optional step here is to move the working directory of the service to its program directory. I always do this to simplify program configuration inputs, logging outputs, etc.

    You can also implement OnPause(), and OnContinue() here. Remember these will never get called if you do not set the CanPauseAndContinue property of the Service. These handlers have no arguments, and should look very similar to the OnStart()/OnStop(), except there should be no building or tearing down of objects.

    Custom commands are out of the scope of this article. However, the OnCustomCommand() event handler is available to extend your service to respond to custom events that you may have other programs execute via the SCM. Use this method to add other interactions to your service (

    [Visual Basic]
    Imports System.ServiceProcess
    Public Class EmptyService
        Inherits System.ServiceProcess.ServiceBase
        Private worker As New worker()
        Protected Overrides Sub OnStart(ByVal args() As String)
            Dim wt As System.Threading.Thread
            Dim ts As System.Threading.ThreadStart
            ts = AddressOf worker.DoWork
            wt = New System.Threading.Thread(ts)
        End Sub
        Protected Overrides Sub OnStop()
        End Sub
        Function GetMyDir() As String
            Dim fi As System.IO.FileInfo
            Dim di As System.IO.DirectoryInfo
            Dim pc As System.Diagnostics.Process
                pc = System.Diagnostics.Process.GetCurrentProcess
                fi = New System.IO.FileInfo(pc.MainModule.FileName)
                di = fi.Directory
                GetMyDir = di.FullName
                fi = Nothing
                di = Nothing
                pc = Nothing
            End Try
        End Function
    End Class

    The Worker Class

    The Worker class controls the thread in which all program processing will occur. It is called when a new thread is started by the Service class, and as mentioned previously, its entry point is the DoWork() method–this is where processing will begin. When DoWork() is called, it attaches to the current thread, gives it a name, and then starts a loop in which processing occurs. For this example, the only processing is to write an entry to the Windows Event Log, sleep, and then write another.

    [Visual Basic]
    Public Class Worker
        Private m_thMain As System.Threading.Thread
        Private m_booMustStop As Boolean = False
        Private m_rndGen As New Random(Now.Millisecond)
        Public Sub StopWork()
            m_booMustStop = True
            If Not m_thMain Is Nothing Then
                If Not m_thMain.Join(100) Then
                End If
            End If
        End Sub
        Public Sub DoWork()
            m_thMain = System.Threading.Thread.CurrentThread
            Dim i As Integer = m_rndGen.Next
            m_thMain.Name = "Thread" & i.ToString
            While Not m_booMustStop
                System.Diagnostics.EventLog.WriteEntry("EmptyService", "Start work: " & m_thMain.Name)
                System.Diagnostics.EventLog.WriteEntry("EmptyService", "Finish work: " & m_thMain.Name)
            End While
        End Sub
    End Class

Sponsored Links