Home > Articles > Programming > Windows Programming

  • Print
  • + Share This
From the author of

Summary

The breadth and power of the .NET Framework combined with the RAD features of a language such as Visual Basic .NET raise the ceiling for developers, while at the same time making it simpler to create robust applications such as Windows services.

Listing 1 contains both the ServiceBase and Installer classes discussed in the article.

Listing 1—A Windows Service Template.

Option Strict On

Imports System.ServiceProcess
Imports System.Configuration
Imports System.Timers
Imports System.ComponentModel
Imports System.Configuration.Install

Public Class MyService : Inherits System.ServiceProcess.ServiceBase

  Public Sub New()
    MyBase.New()

    InitializeComponent()
    'Called only when first loaded not with each start and stop
    ' Set the properties for the service
    With Me
      .ServiceName = "MyService"
      .CanShutdown = True
      .CanStop = True
      .CanPauseAndContinue = False
      .AutoLog = True
    End With
  End Sub

  'UserService overrides dispose to clean up the component list.
  Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
    If disposing Then
      If Not (components Is Nothing) Then
        components.Dispose()
      End If
    End If
    MyBase.Dispose(disposing)
  End Sub

  ' The main entry point for the process
  <MTAThread()> _
  Shared Sub Main()
    Dim ServicesToRun() As System.ServiceProcess.ServiceBase
    ServicesToRun = New System.ServiceProcess.ServiceBase() {New MyService()}
    System.ServiceProcess.ServiceBase.Run(ServicesToRun)
  End Sub

  'Required by the Component Designer
  Private components As System.ComponentModel.IContainer

  <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
    components = New System.ComponentModel.Container()
    Me.ServiceName = "My Service"
  End Sub

  Private _process As Timer
  Private _interval As Long

  Protected Overrides Sub OnStart(ByVal args() As String)
    ' Get the registry values
    _getRegValues()

    ' Configure and turn on the timer
    _process = New Timer(_interval)
    AddHandler _process.Elapsed, AddressOf OnTimer
    _process.Start()
  End Sub

  Private Sub OnTimer(ByVal sender As Object, ByVal e As ElapsedEventArgs)
    ' Timer has gone off
    Me.EventLog.WriteEntry("Waking Up", EventLogEntryType.Information)

    _process.Stop()

    _processWork()

    _process.Start()
  End Sub

  Private Sub _processWork()
    ' Do the work

    ' Update the perf counters
    Try
      Dim counter As PerformanceCounter
      counter = New PerformanceCounter("My Counter", "SomeValue", False)
      counter.IncrementBy(1)
      counter.Dispose()
    Catch e As Exception
      ' Don't care about the exception if any
      Me.EventLog.WriteEntry(e.Message, EventLogEntryType.Error)
    End Try

  End Sub

  Protected Overrides Sub OnStop()
    ' Clean up the timer
    _process.Stop()
    RemoveHandler _process.Elapsed, AddressOf OnTimer
    _process.Dispose()
  End Sub


  Private Function _getRegValues() As Boolean
    ' get values from the registry if needed
  End Function

End Class

<RunInstaller(True)> _
Public Class MyServiceInstall : Inherits Installer

  ' For each service
  Private WithEvents _serviceInstaller As ServiceInstaller
  ' For the entire executable
  Private _processInstaller As ServiceProcessInstaller
  Private _perfCounterInstaller As PerformanceCounterInstaller

  Public Sub New()
    MyBase.New()
    ' Instantiate installers for process and services.
    _processInstaller = New ServiceProcessInstaller()
    _serviceInstaller = New ServiceInstaller()
    _perfCounterInstaller = New PerformanceCounterInstaller()

    ' The services will run under the system account.
    _processInstaller.Account = ServiceAccount.LocalSystem

    ' The services will be started manually.
    _serviceInstaller.StartType = ServiceStartMode.Manual

    ' ServiceName must equal those on ServiceBase derived classes.
    _serviceInstaller.ServiceName = "MyService"
    _serviceInstaller.DisplayName = "My Service"

    ' Set up the perf counters
    Dim counter1 As New CounterCreationData("My Counter", _
      "The description goes here.", _
      PerformanceCounterType.NumberOfItems32)

    _perfCounterInstaller.CategoryName = "My Service"
    _perfCounterInstaller.Counters.Add(counter1)
    _perfCounterInstaller.Counters.Add(counter)

    ' Add installers to collection. Order is not important.
    ' here is where you add performance monitor installers or event log installers
    Installers.Add(_serviceInstaller)
    Installers.Add(_processInstaller)
    Installers.Add(_perfCounterInstaller)

  End Sub

  ' Catch the events
  Public Sub sAfterInstall(ByVal sender As Object, _
    ByVal e As System.Configuration.Install.InstallEventArgs) _
    Handles serviceInstaller.AfterInstall
    ' Log a successful install
  End Sub

  Public Sub sAfterUninstall(ByVal sender As Object, _
    ByVal e As System.Configuration.Install.InstallEventArgs) _
    Handles serviceInstaller.AfterUninstall
    ' Log a successful uninstall
  End Sub

  Public Overrides Sub Install(ByVal state As IDictionary)
    MyBase.Install(state)
    ' Write default values to the registry
  End Sub

  Public Overrides Sub UnInstall(ByVal state As IDictionary)
    ' Delete registry values
  End Sub

End Class
  • + Share This
  • 🔖 Save To Your Account