¿Cómo hacer que un servicio Windows .NET comience justo después de la instalación?

Además del servicio.StartType = ServiceStartMode.Automatic mi servicio no se inicia después de la instalación

Solución

Inserté este código en mi ProjectInstaller

protected override void OnAfterInstall(System.Collections.IDictionary savedState) { base.OnAfterInstall(savedState); using (var serviceController = new ServiceController(this.serviceInstaller1.ServiceName, Environment.MachineName)) serviceController.Start(); } 

Gracias a ScottTx y Francis B.

Puede hacer esto desde su ejecutable de servicio en respuesta a eventos disparados desde el proceso InstallUtil. Anule el evento OnAfterInstall para usar una clase ServiceController para iniciar el servicio.

http://msdn.microsoft.com/en-us/library/system.serviceprocess.serviceinstaller.aspx

He publicado un procedimiento paso a paso para crear un servicio de Windows en C # aquí . Parece que al menos has llegado a este punto, y ahora te preguntas cómo comenzar el servicio una vez que esté instalado. Establecer la propiedad StartType en Automático hará que el servicio se inicie automáticamente después de reiniciar su sistema, pero no comenzará (como ha descubierto) automáticamente su servicio después de la instalación.

No recuerdo dónde lo encontré originalmente (¿quizás Marc Gravell?), Pero sí encontré una solución en línea que le permite instalar e iniciar su servicio ejecutando su propio servicio. Aquí está el paso a paso:

  1. Estructura la función Main() de tu servicio de esta manera:

     static void Main(string[] args) { if (args.Length == 0) { // Run your service normally. ServiceBase[] ServicesToRun = new ServiceBase[] {new YourService()}; ServiceBase.Run(ServicesToRun); } else if (args.Length == 1) { switch (args[0]) { case "-install": InstallService(); StartService(); break; case "-uninstall": StopService(); UninstallService(); break; default: throw new NotImplementedException(); } } } 
  2. Aquí está el código de soporte:

     using System.Collections; using System.Configuration.Install; using System.ServiceProcess; private static bool IsInstalled() { using (ServiceController controller = new ServiceController("YourServiceName")) { try { ServiceControllerStatus status = controller.Status; } catch { return false; } return true; } } private static bool IsRunning() { using (ServiceController controller = new ServiceController("YourServiceName")) { if (!IsInstalled()) return false; return (controller.Status == ServiceControllerStatus.Running); } } private static AssemblyInstaller GetInstaller() { AssemblyInstaller installer = new AssemblyInstaller( typeof(YourServiceType).Assembly, null); installer.UseNewContext = true; return installer; } 
  3. Continuando con el código de apoyo …

     private static void InstallService() { if (IsInstalled()) return; try { using (AssemblyInstaller installer = GetInstaller()) { IDictionary state = new Hashtable(); try { installer.Install(state); installer.Commit(state); } catch { try { installer.Rollback(state); } catch { } throw; } } } catch { throw; } } private static void UninstallService() { if ( !IsInstalled() ) return; try { using ( AssemblyInstaller installer = GetInstaller() ) { IDictionary state = new Hashtable(); try { installer.Uninstall( state ); } catch { throw; } } } catch { throw; } } private static void StartService() { if ( !IsInstalled() ) return; using (ServiceController controller = new ServiceController("YourServiceName")) { try { if ( controller.Status != ServiceControllerStatus.Running ) { controller.Start(); controller.WaitForStatus( ServiceControllerStatus.Running, TimeSpan.FromSeconds( 10 ) ); } } catch { throw; } } } private static void StopService() { if ( !IsInstalled() ) return; using ( ServiceController controller = new ServiceController("YourServiceName")) { try { if ( controller.Status != ServiceControllerStatus.Stopped ) { controller.Stop(); controller.WaitForStatus( ServiceControllerStatus.Stopped, TimeSpan.FromSeconds( 10 ) ); } } catch { throw; } } } 
  4. En este punto, después de instalar su servicio en la máquina de destino, simplemente ejecute su servicio desde la línea de comando (como cualquier aplicación común) con el argumento de instalación de línea de comando para instalar e iniciar su servicio.

Creo que lo he cubierto todo, pero si ve que esto no funciona, hágamelo saber para poder actualizar la respuesta.

Estudio visual

Si está creando un proyecto de instalación con VS, puede crear una acción personalizada que llame a un método .NET para iniciar el servicio. Sin embargo, no se recomienda utilizar acciones personalizadas administradas en una MSI. Vea esta página .

 ServiceController controller = new ServiceController(); controller.MachineName = "";//The machine where the service is installed; controller.ServiceName = "";//The name of your service installed in Windows Services; controller.Start(); 

InstallShield o Wise

Si está utilizando InstallShield o Wise, estas aplicaciones ofrecen la opción de iniciar el servicio. Por ejemplo, con Wise, debe agregar una acción de control del servicio. En esta acción, especifica si desea iniciar o detener el servicio.

Wix

Usando Wix, necesitas agregar el siguiente código xml bajo el componente de tu servicio. Para obtener más información al respecto, puede consultar esta página .

   ///Add any dependancy to your service  

Debe agregar una acción personalizada al final de la secuencia ‘ExecuteImmediate’ en el MSI, usando el nombre del componente del EXE o un lote (inicio sc) como fuente. No creo que esto se pueda hacer con Visual Studio, puede que tenga que usar una verdadera herramienta de autor MSI para eso.

Para iniciarlo justo después de la instalación, genero un archivo por lotes con installutil seguido por sc start

No es ideal, pero funciona …

Utilice la clase .NET ServiceController para iniciarlo o emita el comando de línea de comando para iniciarlo — “net start servicename”. De cualquier manera funciona.

Para agregar a la respuesta de ScottTx, aquí está el código real para comenzar el servicio si lo está haciendo de la manera de Microsoft (es decir, usando un proyecto de instalación, etc.)

(perdonen el código de VB.net, pero esto es a lo que me tengo que atener)

 Private Sub ServiceInstaller1_AfterInstall(ByVal sender As System.Object, ByVal e As System.Configuration.Install.InstallEventArgs) Handles ServiceInstaller1.AfterInstall Dim sc As New ServiceController() sc.ServiceName = ServiceInstaller1.ServiceName If sc.Status = ServiceControllerStatus.Stopped Then Try ' Start the service, and wait until its status is "Running". sc.Start() sc.WaitForStatus(ServiceControllerStatus.Running) ' TODO: log status of service here: sc.Status Catch ex As Exception ' TODO: log an error here: "Could not start service: ex.Message" Throw End Try End If End Sub 

Para crear el controlador de eventos anterior, vaya al diseñador ProjectInstaller donde están los 2 controles. Haga clic en el control ServiceInstaller1. Vaya a la ventana de propiedades debajo de eventos y allí encontrará el evento AfterInstall.

Nota: No coloque el código anterior debajo del evento AfterInstall para ServiceProcessInstaller1. No funcionará, viniendo de la experiencia. 🙂

La solución más fácil se encuentra aquí install-windows-service-without-installutil-exe por @ Hoàng Long

 @echo OFF echo Stopping old service version... net stop "[YOUR SERVICE NAME]" echo Uninstalling old service version... sc delete "[YOUR SERVICE NAME]" echo Installing service... rem DO NOT remove the space after "binpath="! sc create "[YOUR SERVICE NAME]" binpath= "[PATH_TO_YOUR_SERVICE_EXE]" start= auto echo Starting server complete pause