Tuesday, December 23, 2008

How to create a Windows Service in VB.NET

One of the key features provided by Microsoft Visual Studio is the ability to create and run Windows Services. Unlike earlier languages like Visual Basic 6 or C++ where you had to call several API functions and take care of cross language data-type conversions, the .Net Framework provides all the tools required to create a Windows service at one place.


You can use any CLS compliant language like C# or VB.NET to create a Windows service. However, the code and procedure showed here only applies to VB.NET. You also need Visual Studio IDE (Integrated Development Environment) of any version (2005/2008/2010) installed on your machine. Once you have it, just follow these simple steps to create a Windows Service:

[1] Open Visual Studio IDE and create a New Project. In the New Project dialog box, select Visual Basic Projects - Windows Service as the type of the project. Give an appropriate name to the project (lets say MyFirstService), select the location and click OK.

[2] Set some basic properties. Once you have done the above, Visual Studio will create a Solution and Project that you can view in the solution explorer. It also creates a file called Service1.vb that will contain most of the code you will need. In the Solution explorer, double-click on the Service1.vb file. Now you will be able to see its properties in the properties window. Change the Name and ServiceName properties to MyFirstService. In order to add code, right click on the service in solution explorer, and select View Code from the menu. You will notice that Visual Studio has created a new class for your service that inherits from System.ServiceProcess.ServiceBase, the base class for creating any windows service. Visual Studio has also created two overrides for OnStart() and OnStop() events. You can add code here to do certain things like object initialization/destruction, writing logs, etc.

[3] Add code to perform your task. As we are just creating a very basic service, let us perform the following three tasks:
[1] Write a log when the service starts
[2] Write a log after a certain interval (say 15 seconds) while the service is running
[3] Write a log when the service stops

In order to perform the first and third task, all you have to do is append to a text file. However, in order to do the second task, you will have to create a timer. Again, this is not at all difficult as far as coding part is concerned. Just add a variable for the same at the module level. Just type the following declaration at the line below the Inherits statement:

Dim WithEvents timer1 As New System.Timers.Timer

Your new timer object called timer1 is now created. You can add code for the same inside the event procedure. Just select timer1 from the class-name drop-down list on the left, and elapsed from the method-name drop-down list on the right. You can now add the following code to your elapsed event:

Private Sub timer1_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles timer1.Elapsed
WriteLog(Me.ServiceName & " is running ...")
End Sub


This code will keep writing the logs in a text file inside the folder where your service is installed. WriteLog() is not an in-built .NET function, but you will need to create it in order to do this task. Just add the following procedure anywhere in your service’s class declaration:

Private Sub WriteLog(ByVal strMessage As String)
   Dim strPath As String, file As System.IO.StreamWriter
   strPath = AppDomain.CurrentDomain.BaseDirectory & "\MyService.log"
   file = New System.IO.StreamWriter(strPath, True)
   file.WriteLine(strMessage)
   file.Close()
End Sub


In order to write logs at the starting and stopping of the service, change the OnStart() and OnStop() sub procedures as follows:

Protected Overrides Sub OnStart(ByVal args() As String)
   timer1.Interval = 10000
   timer1.Start()
   WriteLog(Me.ServiceName & " has started ...")
End Sub

Protected Overrides Sub OnStop()
   WriteLog(Me.ServiceName & " has stopped ...")
End Sub


As you can see, the OnStart() procedure sets the timer’s interval property to 10 seconds and starts the timer. Calling the start method of the timer is the same as setting its enabled property to True which is false by default. It then calls the WriteLog Function to write the log. Similarly, the OnStop() procedure writes the log to notify that the service has stopped.

[4] Package your service. To package your service into a service installer, just do the following:
1. Right-click on the Service1.vb file in the solution explorer, and click on View Designer.
2. Right-click on the designer and click on Add Installer.
3. You now have an additional file called ProjectInstaller.vb. Double click this file to open.
4. There are two objects on the designer. Click on the first object ServiceProcessInstaller1. In the properties window, change the account property from User to LocalSystem. This will ensure that your service will not require a user’s login in order to run. It could even run while the machine is logged-off.
5. Now click on the second object, ServiceInstaller1. In properties window change the service name to MyFirstService. Also provide the DisplayName property in case you want the display name something other than MyFirstService.
6. You now need to create a setup-project for your service. Right-click on the solution in your solution explorer (that’s the first node in the explorer from top). Select Add-New Project menu to add a new project.
7. Select the Setup and Deployment Projects-Setup Project from the dialog box. Change the name to MyFirstServiceSetup from Setup1.
8. Visual Studio will now create a new folder for the above, named MyFirstServiceSetup. Please note that a file with .msi extension will be created inside the debug subfolder of this folder. This file is the setup file you will need for installing your service.
9. Right click on the Setup Project in the solution explorer. Go to view-custom actions menu. Right click on custom actions and click Add Custom Action. Open Application Folder and select Primary Output from MyFirstService.
10. To compile your service, right-click on your service’s project inside solution explorer and click on Rebuild menu.
11. To add your project output to the setup, right-click on the setup-project in the solution explorer and select add-project output. And click ok.
12. Your setup package is now ready to be built. To do so, right click on the setup project and click Rebuild. The .msi file will be created in the setup project’s debug folder.

[5] Run the setup. Once you have the .msi file you can distribute it anywhere and use it to deploy your service on any machine in the world where .Net Framework is running. Just double click the .msi file to start the setup. It opens a wizard-like interface that asks some basic questions. An important value on the first screen is the Folder to install the service which is “C:\Program Files\MyFirstService” by default. Just remember this folder as you will need to check this folder for the logs that your service will write. Just complete the steps to installation. Your service is now installed and ready to run.

[6] Check the functionality. Now that your service is installed, you can verify it by going to Control Panel-Administrative Tools-Services. In the list of services just find MyFirstService. Right-click on the same and click start to start your service. If everything goes well, you will see a text file called MyService.Log in your installation folder and your application has written the log successfully. Right click on the service and click Stop to stop your service.


This is a very basic windows service and there are several other things you can do in a Windows Service. You can explore the full power exposed by the .Net FCL (Framework Class Library). The FCL allows you to access several key functionalities through it’s various namespaces like System.Windows.Forms to use UI elements, System.IO to do file operations, System.Data for databases, System.XML to work with XML data, System.Threading for Multitasking, System.Net for Network programming, etc.
Please feel free to write to me if you have any queries or suggestions. Happy Programming in VB.NET!

4 comments:

  1. Hai Prahlad Yeri,

    Your tutorial on the basics of the development of the windows service was very useful to me. Thank You.

    Gokul K.

    ReplyDelete
  2. Thank you for sharing this tutorial.

    ReplyDelete
  3. It will definitely ease your work of handling a big project. As a project manager I use scrum in my projects. One of my friends referred me to use the Guide to Scrum Body of Knowledge by http://www.scrumstudy.com. I like the concepts of sprints, daily standup meetings, etc. the SBOK Helped me alot in Understanding how Agile Project Management works.

    ReplyDelete
  4. Merci pour ce tutoriel qui m'a permis d'avancer dans mon projet. Ce n'est pas souvent que je crée des services avec VB et c'est exactement que je cherchais.

    ReplyDelete