2014-06-09 71 views
2

我有WIndows服務應用程序,並希望在主代碼執行時停止服務。我想在的OnStart事件來執行ServiceBase.Stop(),一切工作正常,該服務被停止,但我在事件查看器停止服務沒有錯誤「服務無法啓動。句柄無效」

"Service cannot be started. The handle is invalid" 

任何想法如何停止窗口服務無差錯招人煩的錯誤信息?

public partial class VirtualServerInitService : ServiceBase 
    { 

     public ILogger EventLogger = new EventLogger(); 

     public VirtualServerInitService() 
     { 
      InitializeComponent(); 
     } 

     protected override void OnStart(string[] args) 
     {    
      EventLogger.Write("Starting service!"); 
      new VirtualServerInit(EventLogger).Run(); 
      EventLogger.Write("VirtualServerInit code was executed");    
      Stop();//This code works and also gives error in event viewer 
     } 

     protected override void OnStop() 
     { 
      EventLogger.Write("Stopping service!"); 
     } 
    } 
+0

只需從'OnStart'方法返回,並且如果在進程中沒有更多的前臺線程正在運行,則進程將退出並且服務將被視爲停止。沒有必要在其上調用「停止」。 –

+1

你的'OnStart'應該完成讓SCM知道你已經成功啓動了。 *然後*做你的工作。工作完成後,服務不應該「停止」自己,它應該坐下來等待更多的工作。只有當SCM要求你停止時才停止。 –

+0

@Damien_The_Unbeliever執行OnStart代碼後服務不會自動停止! – Tomas

回答

2

使用一個線程來確保OnStart方法完成。線程池會將您的工作項放在隊列中,一旦線程可用,它將執行您的Run方法,然後在服務上調用Stop。屆時windows service manager已經處理了您的服務的成功開始,因此當調用Stop時,不會將錯誤發送到事件日誌。

protected override void OnStart(string[] args) 
    {    
     EventLogger.Write("Starting service!"); 
     ThreadPool.QueueUserWorkItem(_ => { 
      new VirtualServerInit(EventLogger).Run(); 
      EventLogger.Write("VirtualServerInit code was executed");    
      this.Stop(); 
     }); 
    } 

您可能會考慮讓服務繼續運行並使用CustomCommand來控制是否需要實際工作。爲此,您可以覆蓋OnCustomCommand併發送一個預先確定的整數來請求服務執行特定的任務,例如通過從命令行調用sc virtualsvc control 128

protected virtual void OnCustomCommand(int command) 
{ 
    switch(command) 
    { 
     case 128: 
      new VirtualServerInit(EventLogger).Run(); 
      EventLogger.Write("VirtualServerInit code was executed");    
      // maybe keep state if this only can be run once 
      break; 
     default: 
      EventLogger.Write(String.Format("Unknown control code:{0}", command));    
      break; 
    } 
}