OK, so you want to create a windows service and you’re not a .NET guru? This is exactly what got me in trouble with my wife. It started off easy enough, but before the weekend was through, my wife was getting on to me for spending so much time at the computer. She thought that I should be spending quality time with our family, imagine that. I told her that I was doing some ‘personal’ research, that, “no, it’s not work honey” and “I’m trying to learn some new technology”, “think of it as reading a book, only on the computer…” Inanities like that, she wasn’t having any of it, of course. Regardless, I am glad to report, I figured it out and just in the nick of time, too.
This guide is the result of long hours, a lot of googleing and frustration. Now, using the GUI and some strategically inserted code, I can create a functional .NET Service skeleton in just under 5 minutes. If you are looking for the easy way to create a .NET service, using the GUI, you won’t be disappointed – read on.
First Things First – Requirements
If you are reading this guide and want to try this out in your own development environment, here is what you will need:
Microsoft Visual Studio .NET (2003 is what I use)
Visual C#
.NET Framework
Starting Up the Environment
In order to work with this guide, you will need to start two programs:
Microsoft Visual Studio .NET 2003
Visual Studio .NET 2003 Command Prompt
The Studio is found in the folder:
Microsoft Visual Studio .NET 2003
The Command Prompt is found in the folder:
Microsoft Visual Studio .NET 2003\Visual Studio .NET Tools
You will need the command prompt for installing and uninstalling the service later in this guide.
12 Steps to Service Bliss
Overview
1. Create a Project
2. Browse the Autogenerated Code
3. Rename the .cs File
4. Rename the main Class
5. Add the Service Installer/Uninstaller
6. Create a Timer
7. Do Something Useful
8. Build the Service
9. Install the Service
10. Run the Service
11. Stop the Service
12. Uninstall the Service
By the end of this guide you should have a fair understanding of how to create a working .NET service and install/uninstall it in development.
If you have not already started the IDE, do so now.
Details
1. Create a Project
a. Click the IDE menu item: File-New-Project
or just click the New Project button from the Start Page
the New Project dialog will pop up.
b. Select Visual C# Projects.
c. Select Windows Service from the Templates window.
d. Type a descriptive name into the Name field, something like timedService.
e. Change the location if you don’t like it (optional).
f. Click OK.
2. Browse the Autogenerated Code
The IDE will autogenerate some code and drop you into Service1.cs [Design] view.
To look at the generated code, right click the window and select – View Code. I highly recommend you at least skim the autogenerated code.
When you think you’ve seen enough, Click back to Service1.cs [Design] view.
3. Rename the .cs File
First, let’s change the name of the .cs file to something more applicable. To do this, find the Solution Explorer – usually the top right window. If you cannot see the window anywhere, click the IDE menu item: View-Solution Explorer.
a. Expand the timedService Project(or whatever you named your project)
b. Right Click on Service1.cs
c. Click Rename
d. Name it something like timedService.cs
You will notice that the design view tab now shows timedService.cs [Design] and, if you look at the source code again, that the namespace is timedService.
4. Rename the main Class
While the namespace has been changed to timedService, the name of the class is a generic – Service1, not descriptive and not helpful, we will change it. To do so, find the Class View window. It is usually in the top right window as a tab behind the Solution Explorer. If you cannot see the window anywhere, click the IDE menu item: View – Class View.
a. Expand the timedService Project by clicking the + sign to the left of the name.
b. Expand the timedService Code Namespace.
c. Right Click on the Service1 Code Class.
d. Click Properties. Find the Properties window, usually the bottom right window. If you cannot see the window anywhere, click the IDE menu item: View-Properties Window. Make sure that Service1 CodeClass is showing in the dropdown at the top of the properties window. Below that you will see a Misc property, expand it if it is not already.
e. Click the text field to the right of (Name)
f. Type in something like C_TimedService or whatever you like that helps you to remember that this is the Class that contains our service logic. You will see the changes once the focus changes from the text field, ie. Press enter, tab, click on another window, whatever. It is sad, but the change of name is not complete until we replace the name Service1 in the Main and Initialize Component methods.g. Click back to timedService.cs code view.
h. Type Ctrl-H to bring up the Replace dialog or from the IDE main menu – select Edit – Find and Replace – Replace.
i. Type Service1 into the ‘Find what’ edit box
j. Type C_TimedService into the ‘Replace with’ edit box
k. Click the Replace All button – should result in 3 occurrence(s) replaced.
Now, let’s flesh out the service by adding the ability to actually install and uninstall the service.
5. Add the Service Installer/Uninstaller
In order to actually be able to install our program as a service requires hooks into the Windows Service API and can be rather involved from a programmatic standpoint. You should be glad that the IDE abstracts the details away from the programmer so gracefully. This abstraction makes adding an installer, a piece of cake.
a. Click back to the timedService.cs [Design] window.
b. Right Click in the window.
c. Select Add Installer. The view will change to ProjectInstall.cs [Design] and there will be two icons added to the view, serviceProcessInstaller1 and serviceInstaller1.
d. Switch to the Properties Window – serviceInstaller1 System.ServiceProcess.ServiceInstaller should be selected.
e. Change the (Name) property to something like timedServiceInstaller
f. Change the ServiceName property to something like timedService – this is the display name that will show up in Administrative Tools – Services.
g. Select serviceProcessInstaller1 System.ServiceProcess.ServiceProcessInstaller from the Properties Window dropdown.
h. Change the (Name) property to something like timedServiceProcessInstaller.
i. Change the Account to LocalSystem by selecting it from the dropdown that will appear when you click to the right of Account.
The program is now installable and uninstallable as a service, however, the program does not really do anything, yet. We will fix that.
6. Create a Timer
In this step we will create a 30 second timer with the idea that our service will do something every 30 seconds.
a. Click back to the timedService.cs [Design] window.
b. Click the Toolbox, if you cannot see the Toolbox anywhere, click the menu item: View – Toolbox and you may as well click the Push Pin icon in the top right of the window, so it will stay in the foreground.
c. Click the Components* button
d. Double Click the Timer* button (icon that looks like a clock). A timer icon will now appear in the design window.
e. Click the Toolbox’s push pin so it will keep itself out of the way.
f. Click the timer1 icon in the design window and switch to the Properties Window and timer1 System.Timers.Timer should be selected.
g. Verify that the Enabled property is True or change it to True
h. Change the Interval property to 30000 (30 seconds times 1000 milliseconds)
i. Change the (Name) property to something like timer.
We are set to make the service do something useful.
*If either the Components or Timer buttons are not present, right click in the grey area and select Add/Remove Items…
a dialog will pop up and you can select Timer – System.Timers from the .NET Framework Components tab.
7. Do Something Useful
This is the sticky wicket, or is it thicket? What is useful? In our case, we will have our application log a message to a text file, saying that the program is alive and well. This will provide us with a simple, yet effective demonstration the efficacy of our service.
a. Click back to the timedService.cs [Design] window.
b. Double Click the timer icon. This will drop you into the timedService.cs code window and create a method called timer_Elapsed. This is where we will add our logging code.
c. Type (or copy and paste) the code below into the method, between the start and end curly braces:
System.IO.StreamWriter logfile = System.IO.File.AppendText("c:\\log.txt"); logfile.WriteLine("[" + System.DateTime.Now + "]: I am ALIVE!"); logfile.Close();
This is the only coding that we will do, period. The timer_Elapsed method is where you will want to call your class methods for doing the work. Obviously, you can elaborate on this section to your hearts content.
8. Build the Service
Building the service is a breeze.
From the IDE’s main menu, select Build – Build Solution.
If the build succeeded, you will see the line below in the Output window:
Build: 1 succeeded, 0 failed, 0 skipped
If it fails to build it’s probably a typing error or a missed step. Retrace your steps and verify that you haven’t missed anything. If all else fails, email me and I might be able to help.
That’s it, now let’s install the service.
9. Install the Service
This is one of the steps that requires the Visual Studio .NET 2003 Command Prompt. If you have not already started it, start it now and change to the project directory (directory where the exe file was written). You can determine this in the IDE by selecting from the main menu – Project – Properties (timedService must be selected in the Solution Explorer) and looking at the Project – Project Folder field (hover over it for a tooltip or click it to select for pasting into a cd command). If you copy it from there you will need to cd into bin\debug to get to the actual exe.
a. Verify that you are in the correct directory by typing dir, you should see the file timedService.exe in the directory.
b. Type installutil.exe timedService.exe to install the service.
If the install is successful, you will see these two lines:
The Commit phase completed successfully. The transacted install has completed.
Otherwise look at the output, and the files – timedservice.InstallLog and timedservice.InstallState that will have been created, to determine the cause, and retry after correcting the problem.
10. Run the Service
Running the service is what it’s all about.
a. In windows Click Start-Settings-Control Panel.
b. Double click on the Administrative Tools icon.
c. Double click on the Services icon.
d. Click on the timedService entry
e. Click on the Play button (right triangle) at the top of the Services window.
The service should now be running and the Status field should say Started.
To verify that the service is doing what it should, browse to the log.txt file and open it in your favorite text editor. Scroll to the bottom of the file and you will see an entry like this:
[1/2/2004 10:02:00 AM]: I am ALIVE!
Wait a while (more than 30 seconds) and you will see more entries with timestamps 30 seconds apart – you may need to refresh your editor to see the changes.
11. Stop the Service
What goes up, must come down.
a. In windows Click Start-Settings-Control Panel.
b. Double click on the Administrative Tools icon.
c. Double click on the Services icon.
d. Click on the timedService entry
e. Click on the Stop button (square) at the top of the Services window.
The service should now be stopped and the Status field should be empty.
12. Uninstall the Service
While I would like to think that you have found this Service to be the Killer App of all time, I will go ahead and tell you how to uninstall the service. You will need this knowledge in order to be able to develop .NET Services.
This step requires the Visual Studio .NET 2003 Command Prompt. Start it now and change to the project directory (directory where the exe file was written). You will need to cd into bin\debug to get to the actual exe.
a. Close the Services application if it is running.
b. Verify that you are in the correct directory by typing dir, you should see the file timedService.exe in the directory.
c. Type installutil.exe /u timedService.exe to uninstall the service.
If the uninstall is successful, you will see this line:
The uninstall has completed.
Otherwise look at the output to determine the cause and retry after correcting the problem.
Conclusion
The usual development cycle of edit, compile, debug, edit and recompile is applicable with service as well, with two additions:
edit, compile, install, debug, uninstall, edit, recompile, reinstall.
The uninstall and reinstall steps are really only necessary when you make changes that impact either of the Service Installer Objects – timedServiceProcessInstaller or timedServiceInstaller.
I hope that you have found this guide instructive and helpful. I sure could have used it the other day. My wife would have appreciated it. Let me know if there are errors or omissions and I will try to update the guide.
Resources
Here are some good places to look for more information
a. F1 and Shift-F1 – no, really! It’s not the best, but it should be your first line of defense.
b. Google is where you will have the most luck.
c. Got Dot Net is a pretty decent place to visit.
d. Code Project has a lot of source code for .NET.
e. Code Guru has a lot of .NET related material.
f. Microsoft MSDN .NET Framework Home Page – If all else fails, use the source…
g. Download the source
h. Email the author Will Senn.
I have VS.NET 2003 but I don’t seem to find the motivation to install it as it takes a long time (I need to install 2002 first and then upgrade it).
I know that MS is offering a .NET SDK and C# compiler and tools free of charge, but I am not sure if it includes a debugger and if I can use these with SharpDevelop free IDE.
I know how much resource it can take to figure out a (what seems as) simple task when it’s not documented too well. Thank you for your hardwork, I know i will find it useful !
(Sorry Eugenia for earlier)
No, the SDK does not include a free debugger as far as I know.
Yes, there is a free debugger in the SDK.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ne…
This is a good guide to help folks get off the ground when developing win32 .NET console-based services.
I find it frightening how heavily dependent this process is on the visual studio .NET GUI – all just to make a console service?
For Windows users curious how the same could be accomplished on Linux or BSD, one can use the ‘cron’ daemon to run a command every minute, hour, day, month, or day-of-the-week.
For example, the following command will achieve the same result:
echo “[`date ‘+%D %r’`]: I am ALIVE!” >> ~/time_service.log
It appends this line:
[01/05/04 12:10:11 PM]: I am ALIVE!
to the ‘time_service.log’ file in your home directory.
To make the ‘cron’ daemon run this command every minute, type ‘crontab -e’ and add the following:
* * * * * echo “[`date ‘+%D %r’`]: I am ALIVE!” >> ~/time_service.log
The 5 stars represent minute, hour, day, month, and day of the week. In this case, we want to run our command every minute, all the time.
Or, if your service is not interval based and instead is action/reaction based, you can run your executable/script in the background, like this:
> command &
The ‘&’ sends ‘command’ into the background.
If you’re an administrator, you can add your executable to a start up script in /etc, which is similarly easy – just add a single line to a text file.
Does this service you made run in kernel space?
There are a number of other sample on creating .Net based services on http://www.codeproject.com.
To Anonymous, the service runs with the permissions level of the user under whose account the service is running (set during the install, or later via the component manager). Think of it running as a background user.
To the author of the article, can you explain why the timer1 is being contained by the installer design, rather than the service class?
If you have both 2002 and 2003 why deal with SharpDevelop?? I mean its a very nice FREE IDE but doesn’t compare to vs.net.
I know it doesn’t compare. But I don’t want to spend 2 hours installing VS.NET and spend 6 GB of space.
In the meantime since my last message I have already installed the 1.1 SDK and #develop. It took about 500 MB and 20 minutes overall and it will be good enough for a beginning.
You should be able to install the VS.net 2003 upgrade first and feed it the 2002 disk to prove you have the previous version when the install routine asks for it.
Took me a while to find when I was developing my first Windows Service…
When you are ready to start debugging the .NET Windows Service it’s nice to override the OnStart() method and add a sleep (10-15 seconds) there to give you time to attach the debugger before the service executes your code.
Also, when you start the service go back into Visual Studio (I use 2002) and select Debug->Processes. In the window find your service (by executable name) and click the Attach button. Click Close and you will be debugging your service. You can set breakpoints now that will be hit etc. When you are done debugging go back into the Processes window detach from the process.
Hope that helps someone… 🙂
Does this service you made run in kernel space?
No, a cron job does not run in kernel space. In fact, almost nothing runs in kernel space on a typical unix machine. While there can be some (minor) performance gain from running code in kernel space, it is considered bad to put code into the kernel if it doesn’t have to be there. Why? Because any bug in kernel code can easily lead to a crashed system or a security vulnerability. User space is good because it lets the OS do its job–protecting processes from one another.
Just a few comments on the cron ideas (I’ll just comment on them inline):
I find it frightening how heavily dependent this process is on the visual studio .NET GUI – all just to make a console service?
Well, you can write a .NET service as easy as writing the code in a .cs file and compiling it using csc.exe with the correct command-line parameters. No GUI needed.
For Windows users curious how the same could be accomplished on Linux or BSD, one can use the ‘cron’ daemon to run a command every minute, hour, day, month, or day-of-the-week.[i]
Windows provides a command ‘at’ which is similar to cron (granted not as powerful) which you <u>can</u> use to schedule tasks to run at various times using it. Just run ‘at /?’ to see.
[i]Or, if your service is not interval based and instead is action/reaction based, you can run your executable/script in the background, like this:
> command &
The ‘&’ sends ‘command’ into the background.
If you’re an administrator, you can add your executable to a start up script in /etc, which is similarly easy – just add a single line to a text file.
If you run a command using ‘> command &’ does it continue to run if you log out? A Windows Service can be set to run as soon as Windows boots even before any users logs in. Also, with a Windows Service you can configure it to run as any user you’d like.
I think you could loosely compare a Windows Service to a daemon in Unix.
Hi,
The reason that it is so GUI oriented is because, I wanted to show how ‘easily’ it could be done using the GUI – there are a lot of code based tutorials around. Believe it or not, you would think that this type of information would be easily found, but it really isn’t – least not that I could find.
The do something part is simple on purpose, as well – rocket science is left to the user – I provided a shell not the meat.
Your example using echo could be similarly managed in windows with the AT command and a batch file.
Again, it’s just a tutorial – it is educational not robust or useful.
Thanks for the comments.
Will
Worked as advertised, cept my executable ended up in <pathname>inDebug …. is that normal?
Good tutorial, BTW
I meant … my executable ended up in <pathname>inDebug (after I clicked on Build Solution, there is no executable in the root directory of my project directory).
WorknMan:
It should have been <ProjectDir>/bin/Debug if you built it in debug mode – the default and didn’t specify a different directory. To specify the directory simply select Project-Properties from the main menu and select Configuration Properties in the dialog that pops up. Under Outputs you can change the Output Path (bin/Debug) to whatever you like – under the project directory.
In order to actually install it in production (or just to test from another location) simply copy it where you want it to reside and run installutil nameofexe from that location. installutil comes with the .NET framework.
Thanks,
Will
Jeremy,
Stellar hint! I didn’t think of doing it that way, I just attached and then stopped the process – I know, pretty random, yours is a much better way and allows debugging of the startup code.
Thanks,
Will
This was a GREAT article and can only wish more were documentated and easy to read as this (the screen shots were excellent)!!! It was not only useful but informative.
Thanks much
🙂
This article assumes you are installing this on a the local machine – how do I deploy the created service on a third-party computer that does not have VS.NET on it???
Thanks
This article assumes you are installing this on a the local machine – how do I deploy the created service on a third-party computer that does not have VS.NET on it???
Thanks
SharpDevelop has a good debugger that comes from the .Net SDK. SharpDevelop can be used on the .Net SDK because that is what it was designed for. SharpDevelop didn’t create their own compiler just an IDE.
This article assumes you are installing this on a the local machine – how do I deploy the created service on a third-party computer that does not have VS.NET on it???
At the least you’ll need the .NET Framework installed on any computer that you plan to run .NET applications on. InstallUtil.exe comes with all versions of the .NET Framework, AFAIK, so you can always install a .NET Windows Service.
>@Jeremy – At the least you’ll need the .NET Framework installed on any computer that you plan to run .NET applications on. InstallUtil.exe comes with all versions of the .NET Framework, AFAIK, so you can always install a .NET Windows Service.
But how do you se InstallUtil.exe ???
Anon:
type pathtoinstallutilinstallutil nameofexe
from the directory with nameofexe in it, where pathtoinstallutil is something like:
D:WINNTMicrosoft.NETFrameworkv1.1.4322
and nameofexe is something like:
timedservice.exe
as Jeremy pointed out, you get installutil with the framework.
If you are looking for how to create a professional installer – I hate to be coy, but – that’s beyond the scope of my little 15 page tutorial.
Will
Yeah…..2 hours of doing something else…..once you start the install…..lwhy don’t you go and do something else…..like see the outdoors or something for a few hours……once the install starts its not like you have to sit there…..also the 6GB….most of that is the MSDN and disk space is so cheap…..get over it.