Cuando llega la hora de instalar un servicio Windows en .NET, en mucho sitios recomiendan instalar el servicio mediante una utilidad de la línea de comandos llamada installutil.exe

Comandos básicos para instalar y desinstalar un servicio con installutil.exe:

installutil.exe miservicio.exe
installutil.exe /u miservicio.exe

Una vez instalado podéis arrancar y parar el servicio mediante la utilidad net.exe:

net start miservicio.exe
net stop miservicio.exe

Crear un servicio Windows .NET autoinstalable

El problema de installutil.exe es que sólo la encontraras si instalas Visual Studio en el ordenador donde necesitas instalar el servicio. Una solución es crear un proyecto de InstallShield para crear un autoinstalable. Pero yo os cuento una manera mas sencilla de conseguir esto y ahorraros el sufrimiento de utilizar InstallShield 🙂

Antes de nada, el código incluye una directiva DEBUG que permite debugar el servicio como si se tratara de una aplicación de consola. Esto lo expliqué en Debug desde VS.NET de un servicio Windows.

Por último, recomiendo añadir un ProjectInstaller.cs a vuestro servicio tal como explica este enlace en el paso 5. Añadirlo nos permitirá entre otras cosas especificar el tipo de cuenta, el nombre y la descripción del servicio, el modo de arranque, etc.

Código de ejemplo:

using System.ServiceProcess;
using System.Configuration.Install;
using System.Reflection;
using System;
using System.Threading;

namespace MyService
{
    static class Program
    {
        /// 
        /// Punto de entrada principal para la aplicación.
        /// 
        static void Main(string[] args)
        {
            #if (!DEBUG)    
                if (System.Environment.UserInteractive)
                {
                    string parameter = string.Concat(args);
                    switch (parameter)
                    {
                        case "-i":
                        case "-install":
                            try
                            {
                                ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
                            }
                            catch
                            {
                            }
                            break;
                        case "-u":
                        case "-uninstall":
                            try
                            {
                                ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
                            }
                            catch
                            {
                            }
                            break;
                    }
                }
                else
                {
                    ServiceBase[] ServicesToRun;
                    ServicesToRun = new ServiceBase[] 
                    { 
                        new ServiceWatcher()
                    };
                    ServiceBase.Run(ServicesToRun);
                }

            #else
                // debug mode
                ServiceWatcher service = new ServiceWatcher();
                service.Init();
                Thread.Sleep(Timeout.Infinite);
            #endif
        }
    }
}

Básicamente la idea es que se puede tener un servicio autocontenido para instalar y desinstalar utilizando ManagedInstallerClass como se muestra el ejemplo.

De modo que si compilas el servicio en modo RELEASE para instalar el servicio:

miservicio.exe -install

y para desisntalarlo:

miservicio.exe -uninstall