Once in a blue moon I’m tasked with a project whose requirements call for a long-running (or periodically running) application that needs little in the way of user interaction. As I’ve a small cadre of .NET developers and plenty of Windows OS surrounding me, one solution has been to implement a Windows Service.
Creating a Windows Service project in Microsoft Visual Studio 2010 takes all of three or four mouse clicks. What isn’t immediately clear, and what will serve as the topic for this entry, is:
- How to get your Windows Service to run every X seconds/minutes/hours (on a timer)
- How to make your Windows Service installable
- How to read application settings from a .CONFIG file
- How to perform real-time debugging upon your Windows Service
Excited? All right, let’s roll!
How to get your Windows Service to run every X seconds/minutes/hours (on a timer)
In order to get your new Windows Service to run periodically, we make use of the System.Timers.Timer object. The code fragment below illustrates how to add the basic start, stop and timer objects and classes to the automatically-created main file, Service1.vb. I hope it’s self-explanatory.
Public Class Service1
Public thisTimer As System.Timers.Timer
Public IsRunning As Boolean
' This automatically-created subprocedure contains code you want run when the service is started.
Protected Overrides Sub OnStart(ByVal args() As String)
' Set initial variable values.
Me.IsRunning = False
' Create and start a timer that checks every 20 seconds.
thisTimer = New System.Timers.Timer()
thisTimer.Enabled = True
thisTimer.Interval = 20000
thisTimer.AutoReset = True
AddHandler thisTimer.Elapsed, AddressOf thisTimer_Tick
thisTimer.Start()
End Sub
' This automatically-created subprocedure contains code you want run when the service is stopped.
Protected Overrides Sub OnStop()
End Sub
' This subprocedure is of our own creation, used to store code we want this service to actually execute.
Public Sub DoNextExecution()
SyncLock Me
thisTimer.Stop()
' Another execution cycle begins.
thisTimer.Start()
End SyncLock
End Sub
' Each time the timer completes an interval, it executes the code found within this subprocedure.
Private Sub thisTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
DoNextExecution()
End Sub
End Class
I should add that, like you, I was initially concerned about the CPU utilization of using a timer in this fashion. I am happy to report that the Windows Service does idle while no activity except for the timer are running.
How to make your Windows Service installable
The Windows Service requires extra code to be able to be installed onto a Windows machine. Start by adding a new item to the project of the type Installer Class. Following the lead of others, I typically name this class ProjectInstaller.vb. Then right-click on the new class and select View Designer mode.
Visual Studio 2010 unfortunately does not have the controls you require listed in the toolbox by default, so we’ll need to add them to it. Do this by opening the Tools menu and selecting Choose Toolbox Items… In the .NET Framework Components tab, sort by Namespace. Add System.ServiceProcess.ServiceInstaller and System.ServiceProcess.ServiceProcessInstaller and press OK.
Let’s configure the first item, the ServiceInstaller:
- Under the toolbox section Visual Basic PowerPacks, drag a ServiceInstaller into the ProjectInstaller.vb design window. Right-click on it and select Properties.
- Verify that the Parent property is set to ProjectInstaller.
- Change the Service Name property to what you want the service to be called within the list of services in Windows.
- Change the StartType property using the drop-down to Automatic.
Now configure the second item, the ServiceProcessInstaller:
- Under the toolbox section Visual Basic PowerPacks, drag a ServiceProcessInstaller into the ProjectInstaller.vb design window. Right-click on it and select Properties.
- Change the Parent property to ProjectInstaller.
- Change the Account property to LocalSystem.
That’s it – save ProjectInstaller.vb to disk. You can now use the InstallUtil.exe program to actually install your new Windows Service to a machine to begin use of it.
How to read application settings from a .CONFIG file
Nearly every application has environment settings that rarely change but, when they do, need to be easily and quickly modified. A Windows Service project provides this functionality through .CONFIG files. There are two key pieces of knowledge needed to use a .CONFIG file with a Windows Service:
- The .CONFIG file must reside in the same directory as the .EXE that is compiled.
- The .CONFIG file must be named identically to the .EXE file, with a second extension .CONFIG appended to the end.
Thus, if I have compiled SampleService.exe, I create and save a file called SampleService.exe.config to the same directory.
A Windows Service is again by default not set up to use .CONFIG files – but enabling that functionality is a three-click process:
- Right-click References in the project’s Solution Explorer and select Add Reference…
- Add a reference to System.Configuration.
You may now refer to application variables from the .CONFIG file in this manner:
System.Configuration.ConfigurationManager.AppSettings("DirectoryLogs")
The corresponding value would be written in the .CONFIG value as:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="DirectoryLogs" value="E:\Database\logs\MigrationService" />
</appSettings>
</configuration>
How to perform real-time debugging upon your Windows Service
One of the most fantastic features about all of the Visual Studio IDEs is the integrated debug tools. Most people are familiar with the method in which you begin step-by-step debugging of a web application: Start debug mode and navigate to the page using your Web browser.
Debugging a Windows Service is nearly as straightforward: Compile your Windows Service and install it as a service on your local machine (in debug mode). Then, with Visual Studio 2010 still open and using the exact same copy of the code as was just installed:
- Under the Debug menu, select Attach To Process…
- Near the bottom of the window, select Show processes in all sessions.
- Left-click the EXE you compiled to be run as the Windows Service in the list (it might help to sort by Process). Click Attach.
Now, if you place breakpoints at places in your functions that you know will be executed, you’ll be able to take control of the service as it continues to execute.
That covers all of our topics, from getting your Windows Service to periodically execute code to how to bug your service in real time. If you’ve got any comments or questions please leave a comment and I’ll do my best to clarify anything that may be unclear.
Related posts:
- Microsoft TechEd 2010: Microsoft Visual Studio 2010 Tips & Tricks
- Microsoft TechEd 2010: Microsoft Visual Studio 2010 For Web Deployment
- Using FrontPage with Windows 2008 Shared Hosting Servers
- Microsoft TechEd 2010: Developers Are From Mars, Testers Are From Venus
- The Skinny on Longhorn: Windows Server 2008 and IIS7



{ 17 comments }
I’m going to forward this to a friend of mine who’s looking to create a Windows service in Vistual Studio ’10. He’s gonna love having it all spelled out for him like this.
it’s great article, really helpfull, thank you
Very useful article.
I would like to know the following topics:
1. How to fire this service when an alert comes from database.
2. Extract the data from database and put that as a Memory Mapped File
Appreciate your help and effort!
This is a fantastic, easy to follow tutorial, keep up the good work, thanks.
Good Work. Keep it up
Thanks for this. I worked through several other instructions and yours is the first that made it clear – and worked! Nice job.
I agree about the clarity. And it’s hard to make such complicated directions so clear, too!
When I try to attach to my service to debug, it shows as greyed out and I can’t attach to it. Also, the name of the executable in the list is my vshost.exe and not the plain exe that I installed. Ideas?
Hi, nice article. Just as a note, I am having the same problem as Mike (June 21, 2011). Thanks.
Hiya,
I couldn’t get it to work…. Can anyone help? I’m a little lost once I’ve built the project. I think I’ve got everything in tact… Could someone email me that may know how to get this working? My email is john (underscore) sidney (at) hotmail (dot) co (dot) uk
Cheers!
Hiya,
I couldn’t get it to work…. Can anyone help? I’m a little lost once I’ve built the project. I think I’ve got everything in tact… Could someone email me that may know how to get this working? My email is john (underscore) sidney (at) hotmail (dot) co (dot) uk
Cheers!
Error from command window:
Running a transacted installation.
Beginning the Install phase of the installation.
See the contents of the log file for the C:\lrmonitor\Test\JohnService\JohnServi
ce\JohnService.exe assembly’s progress.
The file is located at C:\lrmonitor\Test\JohnService\JohnService\JohnService.Ins
tallLog.
Installing assembly ‘C:\lrmonitor\Test\JohnService\JohnService\JohnService.exe’.
Affected parameters are:
logtoconsole =
assemblypath = C:\lrmonitor\Test\JohnService\JohnService\JohnService.exe
logfile = C:\lrmonitor\Test\JohnService\JohnService\JohnService.InstallLog
Installing service Service1…
Creating EventLog source Service1 in log Application…
An exception occurred during the Install phase.
System.Security.SecurityException: The source was not found, but some or all eve
nt logs could not be searched. Inaccessible logs: Security.
The Rollback phase of the installation is beginning.
See the contents of the log file for the C:\lrmonitor\Test\JohnService\JohnServi
ce\JohnService.exe assembly’s progress.
The file is located at C:\lrmonitor\Test\JohnService\JohnService\JohnService.Ins
tallLog.
Rolling back assembly ‘C:\lrmonitor\Test\JohnService\JohnService\JohnService.exe
‘.
Affected parameters are:
logtoconsole =
assemblypath = C:\lrmonitor\Test\JohnService\JohnService\JohnService.exe
logfile = C:\lrmonitor\Test\JohnService\JohnService\JohnService.InstallLog
Restoring event log to previous state for source Service1.
An exception occurred during the Rollback phase of the System.Diagnostics.EventL
ogInstaller installer.
System.Security.SecurityException: The source was not found, but some or all eve
nt logs could not be searched. Inaccessible logs: Security.
An exception occurred during the Rollback phase of the installation. This except
ion will be ignored and the rollback will continue. However, the machine might n
ot fully revert to its initial state after the rollback is complete.
The Rollback phase completed successfully.
The transacted install has completed.
The installation failed, and the rollback has been performed.
Hi,
did You find a solution for this problem. I´m having the same problem right now?
with regards
Bent
The problem is because you are trying to install the service without administrative rights.
Open the visual studio command prompt with administrative rights and then install using command “installutil .exe”
Try and ask if there is any prblem
Great article…Just a suggestion. If you can have a little piece which does some operations like writing log and pulling data/writing data etc…It will become complete guide.
Keep up good work
Thanks
Perhaps this might seem like a dumb comment, but you might alter your statement, “That’s it – save ProjectInstaller.vb to disk. You can now use the InstallUtil.exe program to actually install your new Windows Service to a machine to begin use of it.” to something that explains as clearly as the rest of your guide HOW to use the InstallUtil.exe program to actually install said service… my only point here, is that at 1 point, I didn’t KNOW HOW to use InstallUtil, and from doing Google searches, finding good examples seemed difficult. Spelling that out as well as you did everything else I believe would be very helpful to people who potentially don’t know how to do what you’re outlining.
Thanks, this was useful.
Very useful – to resolve install issues;
Run InstallUtil from the ‘Visual Studio Command Prompt (2010)’, as Administrator. On Vista or Windows 7 with UAC enabled, instead of left clicking on the Visual Studio Command Prompt, right click and select “Run as Administrator”.
To Install:-
installutil “C:\path-to-my-proj\service.exe”
To Remove/Uninstall:-
installutil /u “C:\path-to-my-proj\service.exe”