Windows Services in C#: Part 2: Adding an Installer for Your Windows Service
This article is one in a five-part series covering the following topics:
- Programming a Windows Service in C#
- Adding an Installer for Your Windows Service
- Getting Your Installer to Start Your Service
- Some Options for Debugging Your Windows Services
- 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. This is particularly true with this subject since most of the work is actually done in the Visual Studio 2005 GUI and not in the code.
Enough with the small talk, let's build this thing!
Adding an Installer for Your Windows Service
Making a Windows Service installer is about the easiest thing to do, once you know how to do it.
1. Select Add > New Project... under the File menu.
This will (as you may have suspected) add a new project to your Solution.
2. Select a Setup Project .
Under Other Project Types > Setup and Deployment, select Setup Project. At this point you should also give your project a name. For my examples my project will simply be called Setup. Click Ok when you're done.
3. Add Project Output to Application Folder.
When you select your Setup Project in the Solution Explorer you're presented with the File System Editor for that project. From here you can specify what files are added to the user's machine and where. This allows you to designate things like what files from the solution should be added to the application's directory and what desktop and start menu items should be created, if any.
To tell your installer that you want the output (executable and support files) from your Windows Service project to be installed on the hard-drive, right-click on Application Folder and select Add > Project Output...
Select your Windows Service Project from the resulting dialog (shown below; mine is SuperService) and select "Primary output" from the selection box. As you can see from the Description, this is the "DLL or EXE built by the project", but will also include the support files for that executable. Click Ok when you're done.
At this point we have our Setup project that will generate an installer that adds our project's files to a folder on our computer. However, the installer won't actually install the service... yet.
This is where the real Visual Studio 2005 magic begins. We're going to get our Setup Project to fully install our service, fully customized and configured, without touching a single line of code.
4. Add a service installer for your Windows Service project.
Open your Windows Service in design view. Right-click anywhere in the blank space and select Add Installer from the right-click menu.
A new class called ProjectInstaller.cs will be added to your project. Open that new class in Design View. You'll see two controls, serviceProcessInstaller1 and serviceInstaller1.
Click on serviceProcessInstaller1 and observe the Properties, particularly the Account property. This lets you specify which user or system account to run the service under. What you select here really depends on what your application does, but for our purposes, we'll set it to LocalSystem.
Next, select serviceInstaller1 and observe its Properties. Several of them are note-worthy:
- Description: In the Server Explorer (Control Panel > Administrative Tools > Services) each service has an optional Description next to its name. This property allows you to assign that description. For example, I've set mine to "Writes to the Event Log."
- DisplayName: If you set this property, the service will be displayed in the Server Explorer as this name instead of the service's real name (dictated by the ServiceName property.)
- ServiceName: The name of the service. It will appear under this name when windows records events for this service (such as when it errors.) This of course does not include the events we're programmatically logging to the Event Log as detailed in Part 1.
- StartType: Here, you have three options:
- Automatic: Start the service when Windows starts. For some reason this does not mean the service will automatically start as soon as it's installed. That's why we'll handle how to start your service after install in our next article.
- Manual: The user (or another program) must manually start the service.
- Disabled:Well... Disabled.
Once you're done playing with your properties, you have to let the Setup Project know you want to use this Project Installer during the installation process. Save your property changes, then click on your Setup Project in the Solution Explorer. You may have noticed that when the Setup Project was selected, the buttons across the top of the Solution Explorer changed. The second-to-last button (to which my cursor is pointing in the image below) is for the Custom Actions Editor.
Click on that fella and the Custom Actions Editor will open. Right-click on Install and select Add Custom Action... from the right-click menu.
From the resulting dialog double-click on Application Folder, then "Primary output from [Your service] (Active)". It should be easy to find since it will probably be the only option. Click Ok when you're done.
You can then rename the thing if you want, or keep the default label.
6. Build and install.
All you have to do now is build your project and test the installer. However, by default the Setup Project is set to not build. This is because the MSI file can take a little while to compile and you probably wouldn't want to have to wait for it every time you built your solution.
When you're ready to test your installer, go to Build > Configuration Manager and check the Build checkbox next to your Setup Project. Then when you build it will compile as well.
To actually run the installer, you don't have to go dig up the MSI file on your hard-drive and run it. All you need to do is go to Project > Install.
I realize being able to install your service but not uninstall it is kinda lame. The "uninstall" portion of this series isn't completed yet, so I'll clue you in on a little secret: It's really really easy. Remember back in step 5 where we added the Custom Install Action? Well, do the exact same thing but for the Uninstall folder, instead. Yeah, that's all there is to it. You don't even need to make anther ProjectInstaller.cs file, or anything.
In the next segment I'll show you how you can get your installer to start the service immediately after installing. Why MS didn't just make this a property option on the installer, I don't know. Perhaps they just wanted to give me the opportunity to write this article!
Continue to Part 3: Getting Your Installer to Start Your Service