Using Winforms to pass custom commands to a Windows .NET 2.0 Service

Tags: Windows Services

If you are a true geek, one of the measurements you set your mind to figure something out and stick with it until you solve the problem.  Some people call it root cause analysis.  The common person calls it crazy.  Normal people do not think like this but computer geeks are a bit different.  Over the years, I have been interested in Windows .NET services.  Ever since .NET 1.0 came out, I thought it would be cool to have my very own service.  I remember a while ago Dave Wanta (Creator of ASPNetEmail) saying, if you develop your own Windows Service, it should allow the service to accept custom commands.  Years have passed but I never gave up the challenge of figuring out how to do this.  I wrote my own service called IISLogsSVCthe 1.0 version doesn't have the ability to pass custom commands.  The 2.0 version should have functionality to accept "on-demand" commands from a Winforms app.

 

This article covers a simple “Hello World” application called “AService” using the .Net 2.0 framework.  Microsoft has made it very simple to do; this used to be reserved for those who knew C/C++.    What does AService do exactly??  Nothing really besides log a few entries in the Application event log.  It does have sample code showing how easy it is to pass custom commands using a WinForms application while the .Net service is running.  I did not find a “Hello world” application like this so I hope my article helps. 

 

One other tip, I found on MSDN the custom commands from 1 to 128 are system reserved values.  Here is the link to the article  hopefully that explains why the first command uses 130.  I was bored and did not want to use 129. :)  Some other cool things AService has a setup project included in the zip file.  When I was first learning how to use Visual Studio 2003 setup projects.  It was a bit overwhelming since I did not have any experience doing this type of thing.  I hope that you find this useful if you are unfamiliar how to distribute a finished project.

 

In conclusion, you could use a nice front-end application written using Winforms while being able to interact with your .NET service.  This article only scratches the surface of what you can do using Winforms and Windows .NET services together.  Enjoy!

 

What is included in the Solution?

 

Three Visual Studio 2005 projects

  • AService -- the .NET service code
  • AServiceGUI – the Winforms application
  • AServiceSetup – A setup project to distribute the application

Requirements

  •  .Net 2.0 framework installed

Where do I download the code?

Reference Links

 

Sample code - The WinForms application

 

Public Class Form1

 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRunCommand.Click

        If cboSelectCommand.Text.ToString.ToLower = "<select command>" Then

            MessageBox.Show("You forgot to select a command, please try again")

            cboSelectCommand.Focus()

        Else

            For Each service As System.ServiceProcess.ServiceController In ServiceProcess.ServiceController.GetServices

                If Me.ServiceController1.ServiceName.ToLower.Trim = service.ServiceName.ToLower.Trim Then

                    Select Case cboSelectCommand.Text.ToString

                        Case "130"

                            Me.ServiceController1.ExecuteCommand(130)

                        Case "131"

                            Me.ServiceController1.ExecuteCommand(131)

                        Case Else

                            Me.ServiceController1.ExecuteCommand(132)

                    End Select

                End If

            Next

        End If

    End Sub

 

    Private Sub ToolBar1_ButtonClick_1(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolBarButtonClickEventArgs) Handles ToolBar1.ButtonClick

        Dim Log As New EventLog

        Log.Source = "Application"

 

        Select Case e.Button.ImageIndex

            Case 0 'open

                If Me.ServiceController1.Status = ServiceProcess.ServiceControllerStatus.Stopped Then

                    Me.ServiceController1.Start()

                    Me.ServiceController1.Refresh()

                    lblSVCStatus.ForeColor = Color.Green

                    lblSVCStatus.Text = "Started"

                    MessageBox.Show("Service Started")

                End If

            Case 1 'Run Service Now

                If Me.ServiceController1.Status = ServiceProcess.ServiceControllerStatus.Running Then

                    Me.ServiceController1.Stop()

                    Me.ServiceController1.Refresh()

                    lblSVCStatus.ForeColor = Color.Red

                    lblSVCStatus.Text = "Stopped"

                    MessageBox.Show("Service Stopped")

                End If

            Case 2

                If Me.ServiceController1.Status <> ServiceProcess.ServiceControllerStatus.Running Then

                    If MessageBox.Show("The Service is not started", "Start Service", MessageBoxButtons.YesNoCancel) = Windows.Forms.DialogResult.Yes Then

                        'Start the service if the client wants

                        Me.ServiceController1.Start()

                        Threading.Thread.Sleep(5000)

                        Me.ServiceController1.Refresh()

                        For Each service As System.ServiceProcess.ServiceController In ServiceProcess.ServiceController.GetServices

                            If Me.ServiceController1.ServiceName.ToLower.Trim = service.ServiceName.ToLower.Trim = True Then

                                Me.ServiceController1.ExecuteCommand(130)

                                Log.WriteEntry("Ran the command:" & System.DateTime.Now())

                                lblSVCStatus.ForeColor = Color.Green

                                lblSVCStatus.Text = "Started"

                            End If

                        Next

                    End If

                Else

                    MessageBox.Show("Process will not run, AService is already started", "Process will not run, AService is already started", MessageBoxButtons.OK)

                End If

        End Select

 

        Log.Close()

        Log.Dispose()

    End Sub

 

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        For Each service As System.ServiceProcess.ServiceController In ServiceProcess.ServiceController.GetServices

            If Me.ServiceController1.ServiceName.ToLower.Trim = service.ServiceName.ToLower.Trim = True Then

                If Me.ServiceController1.Status = ServiceProcess.ServiceControllerStatus.Running Then

                    lblSVCStatus.ForeColor = Color.Green

                    lblSVCStatus.Text = "Started"

                ElseIf Me.ServiceController1.Status = ServiceProcess.ServiceControllerStatus.Stopped Then

                    lblSVCStatus.ForeColor = Color.Red

                    lblSVCStatus.Text = "Stopped"

                Else

                    lblSVCStatus.ForeColor = Color.DarkBlue

                    lblSVCStatus.Text = "Unknown"

                End If

 

            End If

        Next

    End Sub

 

    Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click

        Me.Close()

    End Sub

End Class

 

 

Sample code - The Windows Service Code

 

Public Class AService

    Protected Overrides Sub OnStart(ByVal args() As String)

        ' Add code here to start your service. This method should set things

        ' in motion so your service can do its work.

    End Sub

 

    Protected Overrides Sub OnStop()

        ' Add code here to perform any tear-down necessary to stop your service.

    End Sub

 

    ' Handle a custom command.

    Protected Overrides Sub OnCustomCommand(ByVal command As Integer)

        Select Case command

            Case 1

                System.Diagnostics.EventLog.WriteEntry("AService", "I selected :" & command.ToString())

            Case 2

                System.Diagnostics.EventLog.WriteEntry("AService", "I selected :" & command.ToString())

            Case Else

                System.Diagnostics.EventLog.WriteEntry("AService", "I selected :" & command.ToString())

        End Select

 

    End Sub 'OnCustomCommand

End Class

 

Picture of A Service GUI (The Winforms app that controls the service)

 

AService by Steve Schofield

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Enjoy!!