2012-08-30 62 views
12

我有这段代码运行powershell脚本,如果我的服务正在启动或停止。ServiceController状态不能正确反映实际的服务状态

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(); 
    } 

它的正常工作,当我杀了从命令提示符 但我的服务,即使我的服务启动并运行,PowerShell脚本继续执行本身(它附加在计算机上的文件) 任何想法,为什么?

+0

要说PowerShell与这个问题是正交的,真正的问题是:为什么我的'StartPending' /'Stopped'检查不能正常工作? –

+0

你有没有试过把断点看看究竟发生了什么? –

回答

28

ServiceController.Status财产并不总是生活;它是第一次懒惰评估它的请求,但(除非要求)只有那个时候;后续查询Status不会通常检查实际的服务。要强制这一点,添加:

sc.Refresh(); 

.Status前检查:

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

没有这种sc.Refresh(),如果它是Stopped(例如)开始,它将总是Stopped

+2

谢谢你的;这是相当空白的讨厌... – Will

+0

呃!严重的是,微软?为什么不建立一个刷新到'状态'调用本身(就像我可能最终会做自己)?或者至少有一个'Status.Refresh'方法来显而易见。 – SteveCinq

+1

哇! @Marc你做了我的一天。明白我们不得不调用sc.Refresh()来确定最新状态。 –