Search code examples
c#.netdeploymentwindows-servicesinstallutil

Install a .NET windows service without InstallUtil.exe


I have a standard .NET windows service written in C#.

Can it install itself without using InstallUtil? Should I use the service installer class? How should I use it?

I want to be able to call the following:

MyService.exe -install

And it will have the same effect as calling:

InstallUtil MyService.exe

Solution

  • Yes, that is fully possible (i.e. I do exactly this); you just need to reference the right dll (System.ServiceProcess.dll) and add an installer class...

    Here's an example:

    [RunInstaller(true)]
    public sealed class MyServiceInstallerProcess : ServiceProcessInstaller
    {
        public MyServiceInstallerProcess()
        {
            this.Account = ServiceAccount.NetworkService;
        }
    }
    
    [RunInstaller(true)]
    public sealed class MyServiceInstaller : ServiceInstaller
    {
        public MyServiceInstaller()
        {
            this.Description = "Service Description";
            this.DisplayName = "Service Name";
            this.ServiceName = "ServiceName";
            this.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
        }
    }
    
    static void Install(bool undo, string[] args)
    {
        try
        {
            Console.WriteLine(undo ? "uninstalling" : "installing");
            using (AssemblyInstaller inst = new AssemblyInstaller(typeof(Program).Assembly, args))
            {
                IDictionary state = new Hashtable();
                inst.UseNewContext = true;
                try
                {
                    if (undo)
                    {
                        inst.Uninstall(state);
                    }
                    else
                    {
                        inst.Install(state);
                        inst.Commit(state);
                    }
                }
                catch
                {
                    try
                    {
                        inst.Rollback(state);
                    }
                    catch { }
                    throw;
                }
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine(ex.Message);
        }
    }