2016-05-16 135 views
0

我創建了Windows服務應用程序。它根據app.config文件中包含的應用程序設置運行。它將同時安裝在不同的位置(網絡,PC)。每個位置都需要在app.config文件中設置自己的參數。所以我不希望它在安裝後自動運行。通過這樣做,每個位置的用戶將能夠打開配置文件並對其進行更改。然後他們可以開始服務。但在此之後,服務將永遠運行。即使他們重新啓動窗口,它也會在Windows打開後自動運行。第一次手動啓動後自動運行windows服務

這是我的安裝程序類。安裝後它不會自動運行。那很好。但是,如果我手動運行它並重新啓動PC,當重新啓動完成時,它仍然等待手動啓動。我該怎麼辦?

public partial class MyServiceInstaller : System.Configuration.Install.Installer 
{ 
    ServiceInstaller _serviceInstaller = new ServiceInstaller(); 
    ServiceProcessInstaller _processInstaller = new ServiceProcessInstaller(); 
    string _serviceName = "MyService"; 
    string _displayName = "My Service"; 
    string _description = "My Service - Windows Service"; 

    public MyServiceInstaller() 
    { 
     InitializeComponent(); 

     this.BeforeInstall += new InstallEventHandler(MyServiceInstaller_BeforeInstall); 

     _processInstaller.Account = ServiceAccount.LocalSystem; 

     _serviceInstaller.StartType = ServiceStartMode.Automatic; 
     _serviceInstaller.Description = _description; 
     _serviceInstaller.ServiceName = _serviceName; 
     _serviceInstaller.DisplayName = _displayName; 

     Installers.Add(_serviceInstaller); 
     Installers.Add(_processInstaller); 
    } 

    protected override void OnCommitted(System.Collections.IDictionary savedState) 
    { 
     ServiceController sc = new ServiceController(_serviceName); 

     if (sc.Status != ServiceControllerStatus.Running) 
     { 
      TimeSpan timeout = TimeSpan.FromMilliseconds(10000); 
      sc.Start(); 
      sc.WaitForStatus(ServiceControllerStatus.Running, timeout); 
      sc.Stop(); 
     } 
     else 
     { 
      RestartService(10000); 
     } 
    } 

    private void RestartService(int timeoutMiliseconds) 
    { 
     ServiceController service = new ServiceController(_serviceName); 

     int millisec1 = Environment.TickCount; 
     TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMiliseconds); 

     service.Stop(); 
     service.WaitForStatus(ServiceControllerStatus.Stopped, timeout); 

     int millisec2 = Environment.TickCount; 
     timeout = TimeSpan.FromMilliseconds(timeoutMiliseconds - (millisec2 - millisec1)); 

     service.Start(); 
     service.WaitForStatus(ServiceControllerStatus.Running, timeout); 
    } 

    void MyServiceInstaller_BeforeInstall(object sender, System.Configuration.Install.InstallEventArgs e) 
    { 
     List<ServiceController> services = new List<ServiceController>(ServiceController.GetServices()); 

     foreach (ServiceController s in services) 
     { 
      if (s.ServiceName == this._serviceInstaller.ServiceName) 
      { 
       ServiceInstaller ServiceInstallerObj = new ServiceInstaller(); 
       ServiceInstallerObj.Context = new System.Configuration.Install.InstallContext(); 
       ServiceInstallerObj.Context = Context; 
       ServiceInstallerObj.ServiceName = _serviceName; 
       ServiceInstallerObj.Uninstall(null); 
      } 
     } 
    } 
} 
+0

您的代碼似乎將啓動類型設置爲自動。你可以檢查事件日誌,看看你的服務是否試圖自動啓動,但失敗。如果您的服務依賴尚未開始的其他服務,則會發生這種情況。 – sgmoore

+0

@sgmoore感謝您的評論。我意識到我的代碼依賴於其他一些代碼,在重啓之後需要等待一段時間才能執行。請將此作爲答案寫下,我會標記它。 –

回答

0

您的代碼似乎已將啓動類型設置爲自動。

你可以檢查事件日誌,看看你的服務是否試圖自動啓動,但失敗。如果您的服務依賴尚未開始的其他服務,則會發生這種情況。

+0

謝謝,因爲依賴關係,它失敗。重啓後應該等待一段時間才能成功執行。因此,將安裝程序的DelayedAutoStart值設置爲true解決了問題。 –

0

服務啓動後可以使用sc config修改啓動類型。

例如。

sc config yourservicename start=auto 

或者您可以使用ChangeServiceConfig

+0

謝謝,但是它的啓動類型在安裝完成後似乎已經是Automatic。所以,不需要改變它。用戶也永遠不會運行任何cmd命令。 –

+0

@OrkunBekar如果啓動類型是自動的,那麼在Windows重新啓動服務必須啓動之後,但由於某種原因,它會失敗,請查看EventLog中的服務錯誤。 – BWA

+0

@orkunbekar如果開始類型設置爲自動,它將在重新啓動時自動啓動。但是將啓動類型設置爲自動並不意味着「立即啓動」。您必須手動執行初始啓動。另外,它並不意味着「在停止/崩潰後重新啓動」,這有獨立的設置。 – derpirscher

1

通過下載名爲TopShelf的NuGet軟件包,可以使您的工作變得更加簡單。

簡單地總結一下,從他們page報價:

Topshelf是使用.NET框架 寫託管服務的框架。服務創建簡化,允許開發人員 創建一個簡單的控制檯應用程序,該應用程序可以使用Topshelf作爲 服務進行安裝。原因很簡單:與服務相比,調試控制檯應用程序更容易得到 。一旦 應用程序經過測試並準備投入使用,Topshelf可以輕鬆地將 作爲服務安裝。

相關問題