2012-08-30 59 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()來確定最新狀態。 –