Tuesday, February 19, 2008

Windows Services in C#: Part 3: Getting Your Installer to Start Your Service

In Part 2 we discussed how to add an installer for the Windows Service we wrote in Part 1. Today, we'll learn how we can tell the Installer to start our service after it has been installed.

This article is one in a five-part series covering the following topics:
  1. Programming a Windows Service in C#
  2. Adding an Installer for Your Windows Service
  3. Getting Your Installer to Start Your Service
  4. Some Options for Debugging Your Windows Services
  5. Adding an Uninstaller for Your Windows Service

The examples in this series are written in C#, but this should help anyone out there wanting to do this on the .NET 2.0 Framework no matter if they're using C#, VB.Net, or any other language. Additionally, the code in this article can be used in any context to start a Windows Service programmatically - not just from an installer.

If you're just jumping in at this article in the series, we've already written our service and added an installer to it. If you'd like a copy of our sample code up until this point (instead of having to go through steps 1 & 2 to recreate it), you can download it here.

On to the code!

Getting Your Installer to Start Your Service
You may have notice that when the installer installs your Windows Service, it doesn't start it automatically, even if the StartType for the service is set to Automatic. Today, we'll learn how we can tell the Installer to start our service after it has been installed.

1. Add the System.ServiceProcess Namespace.
We'll be using the System.ServiceProcess.ServiceController class for this portion of the project, so be sure to add a using statement for System.ServiceProcess to the top of your code:

using System.ServiceProcess;

2. Add an Override for the Install function.
Go into Code View of your Project Installer class (ProjectInstaller.cs in our example.) Add an override for the Install function to your class. All you have to type is "public override void Inst" and hit tab, and Visual Studio's auto-complete should add the class for you, complete with the base.Install line seen below.

Here is the complete code for my example class, with the new bits highlighted:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace SuperService
{
[RunInstaller(true)]
public partial class ProjectInstaller : Installer
{
public ProjectInstaller()
{
InitializeComponent();
}

public override void Install(System.Collections.IDictionary stateSaver)
{
base.Install(stateSaver);
}

}
}
3. Start your Service using the ServiceController.
Since we want our Windows Service to start after the install has finished (we can't exactly start it before it's installed!) we'll add our code to start the service after our base.Install is called. (Note: Optionally, you could have instead done this by adding an event handler for this.AfterInstall and putting your code there. As far as I know, it doesn't make any major difference which way you do it.)

      public override void Install(System.Collections.IDictionary stateSaver)
{
base.Install(stateSaver);
ServiceController controller = new ServiceController("Logger");
controller.Start();
}
Let's break this down for ya'. As I mentioned before, we add our code to start our service after the base.Install line.

We start by instantiating a new ServiceController object, passing the name of our Windows Service as the only parameter. We specified this name earlier in the ServiceName property of our ServiceInstaller object. (Go to Design View of your Project Installer class and click on serviceInstaller1 to view this property.) If this name doesn't match your ServiceName property, you'll get an error (or possibly start the wrong service!)

Finally, we run the Start function of our ServiceController to start our service up. That's about it. You might want to add some code to handle any errors this step may throw so your install doesn't fail if your service fails to start. For example, the code below will trap the error and record it to the event log. If you use it, remember to also add a reference to the System.Diagnostics namespace to the top of your code.

       public override void Install(System.Collections.IDictionary stateSaver)
{
base.Install(stateSaver);
ServiceController controller = new ServiceController("Logger");
try
{
controller.Start();
}
catch (Exception ex)
{
String source = "SuperService Installer";
String log = "Application";
if (!EventLog.SourceExists(source))
{
EventLog.CreateEventSource(source, log);
}

EventLog eLog = new EventLog();
eLog.Source = source;

eLog.WriteEntry(@"The service could not be started. Please start the service manually. Error: " + ex.Message, EventLogEntryType.Error);

}
}

That's all there is to it! Next time, join us to learn a few of your options for debugging your newly-installed service. Until then, feel free to check out some of these other great articles that I used as sources for this series:

Labels:

18 Comments:

At 3/14/08, 5:14 AM, Blogger Draško Sarić said...

Hi,

Your posts on this subject were very helpful and I wish to say one big THANK YOU, MY SAVIOUR! When can we expect other three? :)

 
At 5/20/08, 2:56 PM, Blogger dtrocchio said...

Great set of articles, can't wait for the rest. As you probably know there aren't a lot of good resources out there so this has helped me out tremendously.

Thank you!

 
At 5/26/08, 1:18 PM, Blogger Gael LECROQ said...

Wooow !! It's a great set of articles !! It's well written, clear and sharp !! Great work , Thanks you guy !!!

 
At 9/8/08, 12:32 PM, Blogger vamsi said...

DotNet Devil! Great !!!!!

 
At 12/5/08, 4:47 AM, Blogger Chavda said...

Great work! Now I want to know about the remaining parts. Have you completed working on it?

 
At 12/5/08, 7:17 AM, Blogger Grinn said...

Actually, no. And I don't know that I ever will. I've actually started working for another company now and don't have a lot of time. Sorry guys.

 
At 4/5/09, 7:59 AM, OpenID mscrmsupport said...

I finally reached to right place for searching and searching on internet. Thanks for sharing it with us.
regards
Aamir

 
At 9/8/09, 5:42 AM, Blogger Za pristup slikama said...

Great article: short and precise, straight to the 10 !

Thanks, Peter !

 
At 11/4/09, 1:06 PM, Blogger Dori said...

Awesome series of articles. Just what I was looking for!

I'm assuming you never got around to doing the last two parts? Or if you have, can you link to them?

Thanks!

 
At 1/18/10, 1:06 PM, Blogger Joshua said...

Thank you for your series! I've set the option in my setup project to remove an older version automatically when installing.

However, it gives me the error that the service isn't uninstalled at the very end of the installation process.

How can I tell the setup project to uninstall the actual service when it uninstalls the software?

Thanks again!

 
At 1/26/10, 3:03 AM, Blogger info said...

EXACTLY what I needed. I was looking for a way to start the Windows service RIGHT AFTER installation. THANK YOU!

 
At 1/28/10, 5:03 AM, Blogger abhilash said...

Thank You.. Thank you so much.. it really helped me.. Great Article i was searching for this .. thank u..

 
At 4/28/10, 7:15 PM, Blogger Thomas said...

Worked like a charm, great job, thanks for posting.

 
At 5/5/10, 1:47 PM, Blogger ej said...

Hi i m currently working on desktop search engine as my final project of my degree. i want indexing of files performed through windows services i i read your tutorial it was quite helpful.i created my services in the same manner but when i start services a message appears that services didn't respond in timely fashion .if u could please help me.i m so worried about this.

 
At 12/6/10, 7:56 AM, Blogger Smart said...

Superb Article!. Crisp and up to the point!. Exactly up to the point!. Great work!. Thanks a million!
Ankur

 
At 3/10/11, 2:11 AM, Blogger Radu said...

Hi,

Thank you for this article. Really useful.

 
At 10/3/12, 6:56 AM, Blogger Ram Keshar Thapa said...

Nice, clear and useful article.
Thank you.

 
At 10/4/12, 4:02 AM, Blogger Ram Keshar Thapa said...

Nice, clear and useful article.
Thankyou.

 

Post a Comment

Links to this post:

Create a Link

<< Blog Home