2012-08-30 14 views
12

Tengo este código ejecutando un script de powershell si mi servicio se inicia o se detiene.El estado del ServiceController no refleja correctamente el estado real del servicio

Timer timer1 = new Timer(); 

ServiceController sc = new ServiceController("MyService"); 

protected override void OnStart(string[] args) 
    { 
     timer1.Elapsed += new ElapsedEventHandler(OnElapsedTime); 
     timer1.Interval = 10000; 
     timer1.Enabled = true; 
    } 

    private void OnElapsedTime(object source, ElapsedEventArgs e) 
    { 
     if ((sc.Status == ServiceControllerStatus.StartPending) || (sc.Status == ServiceControllerStatus.Stopped)) 
     { 
      StartPs(); 
     } 
    } 

    private void StartPs() 
    { 
     PSCommand cmd = new PSCommand(); 
     cmd.AddScript(@"C:\windows\security\dard\StSvc.ps1"); 
     PowerShell posh = PowerShell.Create(); 
     posh.Commands = cmd; 
     posh.Invoke(); 
    } 

Está funcionando bien cuando mato a mi servicio de cmd pronta Pero incluso si mi servicio está en funcionamiento, la secuencia de comandos PowerShell continúa ejecutando en sí (que añade un archivo en el ordenador) Cualquier idea de por qué?

+0

¿Sería correcto decir que powershell es ortogonal a esta pregunta, y la pregunta * real * es: ¿por qué mi comprobación 'StartPending' /' Stopped' no funciona correctamente? –

+0

¿Ha intentado poner puntos de interrupción para ver qué está pasando exactamente? –

Respuesta

28

La propiedad ServiceController.Statusno siempre está activa; se evalúa perezosamente la primera vez que se solicita, pero (a menos que se solicite) solo ese momento; consultas posteriores a Statusno normalmente verifican el servicio real. Para forzar esto, añadir:

sc.Refresh(); 

antes de su llegada .Status:

private void OnElapsedTime(object source, ElapsedEventArgs e) 
{ 
    sc.Refresh(); 
    if (sc.Status == ServiceControllerStatus.StartPending || 
     sc.Status == ServiceControllerStatus.Stopped) 
    { 
     StartPs(); 
    } 
} 

Sin sc.Refresh() que, si era Stopped (por ejemplo) un principio, será siempre decir Stopped.

+2

Gracias por eso; Eso es bastante obsoleto ... – Will

+0

¡Uf! En serio, Microsoft? ¿Por qué no compilar una actualización en la llamada 'Status' en sí misma (como probablemente terminaré haciendo yo mismo) ?? O al menos tener un método 'Status.Refresh' para hacerlo obvio. – SteveCinq

+1

Wow Man !! @Marc Me alegraste el día. No es obvio entender que tenemos que llamar a sc.Refresh() para estar seguros sobre el estado más reciente. –

Cuestiones relacionadas