This article describes step-by-step, with screen snapshots, how to create a polling service using VB.NET and Visual Studio 2005. It solves the problem of using timers in a service, in a quick and simple manner.
Over the years, I have leaned on CodeProject to help me get started on many projects that involved programming technologies I was not familiar with at the time. This last project required me to create a service for a set of code I had already written. So, I headed over to CodeProject to figure out if my friends at CodeProject had a good article to do that. I was not disappointed. Mahmoud Nasr had written a highly rated and popular article, Simple Windows Service Sample.
Everything went fine until I needed to add the timer part. There are a great many opinions about which timers to use in a service. And, a Google search will yield many requests and complaints about all of them. I never did find a satisfactory article that explained how to do this seemingly simple thing. In addition, there were issues with multithreading and reentrancy when the timer fires before your task is ready to start over again.
I think I have solved this with a simple and quick solution. So, if you want to run a task repeatedly in the background, without worrying about reentrancy or multiple threading, and if you just want to wrap your code in a Windows Service, here is a very simple and straightforward way to do it.
Using the Code
The code I present, basically, follows the same steps to create a service that MSDN recommends. And, it is very similar to Mahmoud's article. The main difference being that it includes code to do polling, and shows you where you can drop your code in.
Executing the demo will install a service called "Polling Service". It will write an event log entry to the Application Log on your computer, every 30 seconds. The source code is everything you need to build the demo. It is also the final result of following the steps in this article.
1. Create New Service Project
Start by creating a new Visual Studio Project. Startup Visual Studio 2005.
Select the "Windows Service" template, and name the project.
Drag and drop the "Event Log" component from the toolbox onto your new service designer window.
Set the "ServiceName" and "(Name)" property to the name of your new service.
Set the "Log" property to "Application". Set the "Source" property to the name of your new service.
Enter the wrapper code for your service.
You can cut and paste the following code into the code window for your service. Change variable names and message text as appropriate for your service.
Public Class PollingService
Private m_oPollingThread As New Thread( _
New System.Threading.ThreadStart(AddressOf PollProcess))
Protected Overrides Sub OnStart(ByVal args() As String)
EventLog1.WriteEntry("PollingService is starting.")
Protected Overrides Sub OnStop()
EventLog1.WriteEntry("PollingService is stopping.")
Private Sub PollProcess()
EventLog1.WriteEntry("PollingService service polling thread started.")
Private Sub PollingPass()
EventLog1.WriteEntry("PollingService service polling pass executed.")
Catch ex As System.Exception
EventLog1.WriteEntry("PollingService encountered an error '" & _
ex.Message & "'", EventLogEntryType.Error)
EventLog1.WriteEntry("PollingService service Stack Trace: " & _
Notes About the Code
When the service is started, in the "
OnStart" method, a new thread is started. You must start a new thread because the service manager controls this process. If you simply call the polling process from the
OnStart method, the service manager would complain that the service does not respond. In other words, the
OnStart method does not return control to the service manager.
That new thread loops indefinitely, and the only way to stop it is to issue the
Abort command on the thread, which we do when we stop the service in the "
The thread process continually executes two commands: the command to wait for a specified period of time, and then the command to run your code.
In my example, I have added exception checking to write any problems to the event log. The event log is the only way to debug a service during the startup time, as you can only interactively debug a service by attaching to the process "after" it has already started.
That's it for your service. Pretty simple, eh? Replace the comment "Do Stuff Here..." with the code you want to run on a periodic basis.
You can change the period that the service waits between executing your code, by changing the sleep time. It is specified in milliseconds, and there's 1000 milliseconds in a second.
2. Add Project Installer
The service is done. However, to run it, we can't just press the F5 button. We have to install the service. The following describes how to include in the project all the "stuff" needed to install the service on a computer.
Right click on the designer pane for your service, and select the option "Add Installer".
Everything is setup for you. You can choose how your service starts, by setting the "StartType" property. The default is "Manual". I've set it to "Automatic" in my example.
You can also specify which account the service runs under when it is started. Select the "ServiceProcessInstaller" component and set the "Account" property. The default is "User Account", and you will need to specify the username and password at installation time. I have set the example to use "LocalSystem" which does not require a username or password. Most Windows services run this way.
OK, now, when your application is run using the /install option, it will install itself as a service on your computer. And, when /uninstall is specified, it will remove the service from your computer.
Now, all we have to do is build the thing and resolve any build errors. To do that, select the properties of "My Project" in the Solution Explorer.
Change the "Startup Object" to the name of your service.
Now, build your solution.
3. Add Setup Project
OK, you have a service, let's add a setup procedure to this project to make it easy for others to install and use your funky new service.
Choose the "Setup Wizard" and choose a name. You can use the same name as your setup project.
Follow the setup wizard prompts.
Now, you need to add a custom action so that after all the files are copied over, the program is setup as a service.
We are done setting up the setup project. Now, build it.
4. Run It
Your service has been installed. Now, go to the Service Manager and start it. The Service Manager can be found in "Administrative Tools".
Start the service. Even though we set it to start automatically, it does not start automatically after we install the service. It will start automatically when the computer starts up.
Now, examine the event log to verify our service has started and is running successfully. The Event Viewer can be found in "Administrative Tools".
5. Notes on Uninstall
This example will continue to write event log messages to your application log every 30 seconds. Once you are convinced it works, you will want to uninstall it.
To do that, simply run the same .msi file that you ran to install it in the first place. It will prompt to Repair or Remove. Choose the Remove option.
Another way to remove your service is through the 'Add/Remove Software' Control Panel option. If you have lost or overwritten your .msi file with a new version, this is the only way to remove your service.
Before uninstalling a service: be sure to close the Services Viewer. If you do not and you have your service highlighted in the Service Viewer, the uninstall will not be able to remove your service. This is because the Service Viewer "locks" the service that is highlighted. The uninstaller will instead "mark" the service for deletion. When this happens, you cannot reinstall the service until the marked service is removed. There is no way to remove the marked service except by restarting the computer.