2009-06-24 13 views
103

Tengo un servicio de Windows que instalo usando InstallUtil.exe. Aunque configuré el Método de inicio en Automático, el servicio no se inicia cuando está instalado, tengo que abrir manualmente los servicios y hacer clic en Inicio. ¿Hay alguna manera de iniciarlo ya sea a través de la línea de comando o a través del código del Servicio?Iniciar automáticamente un servicio de Windows en la instalación

Respuesta

180

En la clase de instalación, agregar un controlador para el evento AfterInstall. Luego puede llamar al ServiceController en el controlador de eventos para iniciar el servicio.

using System.ServiceProcess; 

public ServiceInstaller() 
{ 
    //... Installer code here 
    this.AfterInstall += new InstallEventHandler(ServiceInstaller_AfterInstall); 
} 

void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e) 
{ 
    using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName)) 
    { 
     sc.Start(); 
    } 
} 

Ahora cuando se ejecuta InstallUtil en su instalador que instalará y luego inicie el servicio.

+39

(comentario de una edición propuesta): es mejor usar serviceInstaller.ServiceName, si se cambia el nombre del servicio, usará el nombre correcto sin necesidad de cambiarlo en el código. –

+1

Tampoco estaría de más ajustar el 'ServiceController' en una instrucción de uso. – ChrisO

+0

Necesitaba especificar el id del instalador del servicio en OnBeforeInstall. Algo así como serviceInstaller = serviceInstaller1; donde el serviceInstaller1 es la identificación del diseñador. Hacer esto en OnBeforeInstall hizo que el trabajo anterior fuera perfecto para mí. No lo intenté, pero también es posible que lo haga en la llamada ServiceInstaller(). –

0

El inicio automático significa que el servicio se inicia automáticamente cuando se inicia Windows. Como otros han mencionado, para iniciarlo desde la consola, debe usar ServiceController.

+0

No deseo hacer esto. Estoy buscando hacer esto de una vez desde la línea de comando o desde dentro de las clases de servicio de Windows. – mickyjtwin

+0

Lo siento, mi mal, me perdí el punto donde explícitamente excluyó la posibilidad de iniciarlo en el panel de control. –

5

¿Qué le parece seguir los comandos?

net start "<service name>" 
net stop "<service name>" 
3

Usted puede utilizar la línea de comandos para iniciar el servicio:

net start *servicename* 
2

Uso ServiceController para iniciar su servicio de código.

Actualización: Y más correcta manera de iniciar el servicio de la línea de comandos es utilizar (Service Controller) de comandos en lugar de "red" "sc".

+6

¿Por qué "sc" es una forma "más correcta"? ¿Qué hay de malo con el "inicio de red" (y el cmdlet PSH de inicio de servicio)? – Richard

+1

Porque sc se puede llamar desde una máquina remota, por lo que siempre funciona. – MacGyver

0

Puede utilizar el método GetServices de ServiceController clase para obtener una matriz de todos los servicios. Luego, encuentre su servicio marcando la propiedad ServiceName de cada servicio. Cuando hayas encontrado tu servicio, llama al método Start para iniciarlo.

También debe verificar la propiedad Status para ver en qué estado ya está antes de llamar al inicio (puede estar ejecutándose, en pausa, detenido, etc.).

4

opciones programáticas para servicios de control:

  • código nativo puede utilizados, "Starting a Service". Control máximo con dependencias mínimas pero el mayor trabajo.
  • WMI: Win32_Service tiene un método StartService. Esto es bueno para los casos en los que necesita poder realizar otro procesamiento (por ejemplo, para seleccionar qué servicio).
  • PowerShell: ejecute Start-Service a través de RunspaceInvoke o creando su propio Runspace y usando su método CreatePipeline para ejecutar. Esto es bueno para los casos en los que necesita poder realizar otro procesamiento (por ejemplo, para seleccionar qué servicio) con un modelo de codificación mucho más fácil que WMI, pero depende de la instalación de PSH.
  • aplicación A .NET puede utilizar ServiceController
23

Después de refactorización un poco, esto es un ejemplo de un instalador de ventanas de servicio completo con arranque automático:

using System.ComponentModel; 
using System.Configuration.Install; 
using System.ServiceProcess; 

namespace Example.of.name.space 
{ 
[RunInstaller(true)] 
public partial class ServiceInstaller : Installer 
{ 
    private readonly ServiceProcessInstaller processInstaller; 
    private readonly System.ServiceProcess.ServiceInstaller serviceInstaller; 

    public ServiceInstaller() 
    { 
     InitializeComponent(); 
     processInstaller = new ServiceProcessInstaller(); 
     serviceInstaller = new System.ServiceProcess.ServiceInstaller(); 

     // Service will run under system account 
     processInstaller.Account = ServiceAccount.LocalSystem; 

     // Service will have Start Type of Manual 
     serviceInstaller.StartType = ServiceStartMode.Automatic; 

     serviceInstaller.ServiceName = "Windows Automatic Start Service"; 

     Installers.Add(serviceInstaller); 
     Installers.Add(processInstaller); 
     serviceInstaller.AfterInstall += ServiceInstaller_AfterInstall;    
    } 
    private void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e) 
    { 
     ServiceController sc = new ServiceController("Windows Automatic Start Service"); 
     sc.Start(); 
    } 
} 
} 
+1

Este código me dio los siguientes error/s: Se produjo una excepción durante la fase de instalación. System.InvalidOperationException: se ha producido una excepción en el controlador de eventos OnAfterInstall de System.ServiceProcess.ServiceInstaller. La excepción interna System.InvalidOperationException se lanzó con el siguiente mensaje de error: No se puede iniciar el servicio serviceName en la computadora '.' .. La excepción interna System.ComponentModel.Win32Exception se lanzó con el siguiente mensaje de error: El programa ejecutable que este servicio es configurado para ejecutarse no implementa el servicio. – goamn

+1

Los errores se incautaron una vez que comenté la línea "InitializeComponent()". Creo que esta línea está duplicando todas las otras líneas, ya que los registros parecen mostrar dos cosas idénticas sucediendo juntas antes del error: Instalar el servicio serviceName ... El servicio serviceName se ha instalado correctamente. Creación de EventLog source serviceName en el registro Aplicación ... Instalación del servicio serviceName ... Creación de EventLog source serviceName en el registro Aplicación ... Ocurrió una excepción en el controlador de eventos OnAfterInstall de System.ServiceProcess.ServiceInstaller. – goamn

+0

Realmente salvaste mi día :) Gracias por este útil comentario. Después de comentar la llamada InitializeComponent(), mi servicio también comenzó perfectamente – Konstantin

0

corrompiste su diseñador.Vuelva a agregar su componente de instalador. Debe tener un ServiceInstaller y un serviceProcessInstaller. El instalador de servicios con propiedad Método de inicio establecido en Automático se iniciará cuando se instale y después de cada reinicio.

1

A pesar de seguir exactamente la respuesta aceptada, todavía no pude obtener el servicio para comenzar-- En su lugar, recibí un mensaje de error durante la instalación que indicaba que el servicio que acaba de instalar no se pudo iniciar, ya que no existía , a pesar de utilizar this.serviceInstaller.ServiceName en lugar de un literal ...

final encontré una solución alternativa que hace uso de la línea de comandos:

private void serviceInstaller_AfterInstall(object sender, InstallEventArgs e) { 
     ProcessStartInfo startInfo = new ProcessStartInfo(); 
     startInfo.WindowStyle = ProcessWindowStyle.Hidden; 
     startInfo.FileName = "cmd.exe"; 
     startInfo.Arguments = "/C sc start " + this.serviceInstaller.ServiceName; 

     Process process = new Process(); 
     process.StartInfo = startInfo; 
     process.Start(); 
    } 
0

Sólo una nota: Es posible que haya configurado el servicio de manera diferente con el forma interfaz para agregar un instalador de servicio e instalador de proyecto. En ese caso, reemplace donde dice serviceInstaller.ServiceName con "name from designer" .ServiceName.

En este caso, tampoco necesita los miembros privados.

Gracias por la ayuda.

Cuestiones relacionadas