5,542,300 members and growing! (18,055 online)
Email Password   helpLost your password?
Platforms, Frameworks & Libraries » .NET Framework » General     Intermediate License: The Code Project Open License (CPOL)

Windows Services Can Install Themselves

By W. Kevin Hazzard

Never use the InstallUtil.exe utility that ships with the .NET SDK again.
C# 2.0, C#Windows, .NET, .NET 3.0, .NET 3.5, .NET 2.0, WinXP, Win2003, VistaVS2005, Visual Studio, Dev

Posted: 22 Nov 2007
Updated: 22 Nov 2007
Views: 25,876
Bookmarked: 110 times
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
72 votes for this Article.
Popularity: 8.66 Rating: 4.66 out of 5
3 votes, 4.2%
1
3 votes, 4.2%
2
0 votes, 0.0%
3
2 votes, 2.8%
4
64 votes, 88.9%
5

Introduction

Using the InstallUtil.exe utility that ships with the .NET SDK can be a real pain. It's rarely in the PATH so you probably have to hunt down the utility when you are working on QA and production servers as I do. Installing a Windows Service should be easier. In this short article, I'll show you a way to make your Windows Services install themselves without needing InstallUtil.exe at all.

Assumptions

Let's assume that your service project has a service installer, a service process installer and a class derived from System.Configuration.Install.Installer already. If not, check out Mahmoud Nasr's excellent article on Windows Service development, then come back here.

Key Information

Thanks to Reflector for .NET by Lutz Roeder, it's easy to discover how the InstallUtil.exe utility does its job. After some setup, the InstallUtil.exe tool jumps to a method called InstallHelper in the ManagedInstallerClass in the System.Configuration.Install namespace. And what's really interesting is that the command line arguments passed to InstallUtil.exe as an array of strings are then passed directly to this helper method.

Well, this made me think, "If all InstallUtil.exe does is call the ManagedInstallerClass' InstallHelper method, why can't my service executable do the same thing to install itself on command?" The little class below makes it simple to do just that.

Using the Code

Create a new CS file in your service executable project containing the following code. You may also need to add a reference to the System.Configuration.Install.dll from the Global Assembly Cache if you don't already have one.

using System.Reflection;
using System.Configuration.Install;

namespace gotnet.biz.Utilities.WindowsServices
{
    public static class SelfInstaller
    {
        private static readonly string _exePath =
            Assembly.GetExecutingAssembly().Location;
        public static bool InstallMe()
        {
            try
            {
                ManagedInstallerClass.InstallHelper(
                    new string[] { _exePath } );
            }
            catch
            {
                return false;
            }
            return true;
        }

        public static bool UninstallMe()
        {
            try
            {
                ManagedInstallerClass.InstallHelper(
                    new string[] { "/u", _exePath } );
            }
            catch
            {
                return false;
            }
            return true;
        }
    }
}

Now you need to come up with some sort of convention for knowing when to invoke the installer. Below is just an example of how you might handle this in your Main() method, the entry point to your service. I like the convention of using -i or -install parameters to install the service and -u or -uninstall to uninstall it. I also like to use -c or -console to mean starting the application in a console rather than as a service. However, that's a topic for a different article.

using gotnet.biz.Utilities.WindowsServices;

namespace MyService.WinHost
{
    static class Program
    {
        public static void Main( string[] args )
        {
            if (args != null && args.Length == 1 && args[0].Length > 1
                && (args[0][0] == '-' || args[0][0] == '/'))
            {
                switch (args[0].Substring( 1 ).ToLower())
                {
                    default:
                        break;
                    case "install":
                    case "i":
                        SelfInstaller.InstallMe();
                        break;
                    case "uninstall":
                    case "u":
                        SelfInstaller.UninstallMe();
                        break;
                    case "console":
                    case "c":
                        MyConsoleHost.Launch();
                        break;
                }
            }
            else
                MyWinServiceHost.Launch();
        }
    }
}

Now, assuming my executable is named MyWinSvcHost.exe, I can invoke the installer by running:

C:\> MyWinSvcHost.exe -install

Or to uninstall my service, I would use this:

C:\> MyWinSvcHost.exe -uninstall

Other Ideas

This little bit of code called the SelfInstaller is full of possibilities. You could pass parameters to the InstallMe method to pass on to the ServiceProcessInstaller in your program, for example. Perhaps the domain name, user name and password used to start your service could be passed all the way from your Main() method to the ServiceProcessInstaller. Cool, right? I thought you would like that.

History

  • 22 Nov, 2007 - Initial publication

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

W. Kevin Hazzard


After 16 years as an ardent C++ aficionado, Kevin switched to C# in 2001. Recently, Kevin's been dabbling in dynamically typed languages. Kevin is the Software Architect for Snagajob.com, the #1 source for hourly and part-time employment on the web.

Kevin loves welding, riding motorcycles and spending time with his family. Kevin has also been an adjunct professor teaching software engineering topics at a college in his hometown of Richmond, Virginia since 2000. Check out Kevin's technical blog at www.gotnet.biz for more goodies.
Occupation: Web Developer
Location: United States United States

Other popular .NET Framework articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 25 of 32 (Total in Forum: 32) (Refresh)FirstPrevNext
Subject  Author Date 
QuestionSetting ServiceProcessInstaller attributesmemberChris Newton3:45 28 May '08  
GeneralFor the console lovers ;-)memberAleksei Nickolayev5:06 3 Mar '08  
GeneralRe: For the console lovers ;-)memberW. Kevin Hazzard7:51 6 Mar '08  
GeneralGreat articlemembersrinath g nath19:09 30 Dec '07  
GeneralInstall on first run [modified]memberAshley van Gerven18:55 21 Dec '07  
GeneralRe: Install on first runmemberW. Kevin Hazzard4:54 26 Dec '07  
GeneralRe: Install on first runmemberAshley van Gerven5:13 26 Dec '07  
GeneralCan't start service.memberRicky15:09 27 Nov '07  
GeneralRe: Can't start service.memberW. Kevin Hazzard11:00 29 Nov '07  
GeneralRe: Can't start service.memberRicky13:44 30 Nov '07  
GeneralRe: Can't start service.memberRicky13:54 30 Nov '07  
GeneralI took a different tack [modified]memberPIEBALDconsult17:12 26 Nov '07  
GeneralYou can go further (an alternative approach)memberOleg Shilo16:18 26 Nov '07  
GeneralRe: You can go further (an alternative approach)membertag200119:24 26 Nov '07  
GeneralRe: You can go further (an alternative approach)memberOleg Shilo19:41 26 Nov '07  
GeneralRe: You can go further (an alternative approach)memberOne Smart Motor Scooter7:46 27 Nov '07  
GeneralRe: You can go further (an alternative approach)memberW. Kevin Hazzard10:55 29 Nov '07  
GeneralDoesn't seem to work for memembersmesser21:49 23 Nov '07  
GeneralRe: Doesn't seem to work for mememberW. Kevin Hazzard5:21 24 Nov '07  
GeneralRe: Doesn't seem to work for me [modified]membersmesser5:36 24 Nov '07  
GeneralRe: Doesn't seem to work for mememberW. Kevin Hazzard6:24 24 Nov '07  
GeneralRe: Doesn't seem to work for memembersmesser7:08 24 Nov '07  
GeneralIndispensablemembermunenedumunenedu6:17 23 Nov '07  
GeneralExcellent!memberT1TAN1:23 23 Nov '07  
GeneralJust like Delphi does it.memberstensones0:33 23 Nov '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 22 Nov 2007
Editor: Deeksha Shenoy
Copyright 2007 by W. Kevin Hazzard
Everything else Copyright © CodeProject, 1999-2008
Web20 | Advertise on the Code Project