2016-05-16 3 views
0

Ich habe eine Windows-Dienstanwendung erstellt. Es wird abhängig von den App-Einstellungen ausgeführt, die in der Datei app.config enthalten sind. Es wird gleichzeitig an verschiedenen Orten (Netzwerken, PCs) installiert. Jeder Standort muss seine eigenen Parameter in der app.config-Datei festlegen. Daher möchte ich nicht, dass es nach der Installation automatisch ausgeführt wird. Auf diese Weise können Benutzer die Konfigurationsdatei öffnen und ändern. Dann können sie den Dienst starten. Aber danach wird der Dienst für immer laufen. Auch wenn sie die Windows neu starten, wird es automatisch nach dem Öffnen von Windows ausgeführt.Windows-Dienst automatisch für immer ausführen, nach dem ersten manuellen Start

Hier ist meine Installer-Klasse. Es wird nicht automatisch nach der Installation ausgeführt. Das ist gut. Aber wenn ich es manuell starte und den PC neu starte, wartet der Neustart nach dem Neustart darauf, manuell gestartet zu werden. Was soll ich machen?

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

Ihr Code scheint den Starttyp auf Automatisch zu setzen. Können Sie das Ereignisprotokoll überprüfen, um zu sehen, ob Ihr Dienst versucht, automatisch zu starten, aber fehlgeschlagen. Dies kann passieren, wenn Ihr Dienst von einem anderen Dienst abhängig ist, der noch nicht gestartet wurde. – sgmoore

+0

@sgmoore danke für deinen Kommentar. Ich erkannte, dass mein Code von einem anderen Code abhängt, der einige Zeit warten muss, bevor er nach dem Neustart ausgeführt wird. Schreibe dies bitte als Antwort und ich werde es markieren. –

Antwort

0

Ihr Code scheint den Starttyp automatisch auf Automatisch zu setzen.

Können Sie im Ereignisprotokoll überprüfen, ob Ihr Dienst versucht, automatisch zu starten, aber fehlgeschlagen. Dies kann passieren, wenn Ihr Dienst von einem anderen Dienst abhängig ist, der noch nicht gestartet wurde.

+0

Danke, es scheiterte wegen der Abhängigkeiten. Es sollte einige Zeit nach dem Neustart warten, um erfolgreich ausgeführt zu werden. Wenn Sie also den DelayedAutoStart-Wert des Installationsprogramms auf "True" setzen, wurde das Problem behoben. –

0

Sie können nach dem Start des Dienstes sc config verwenden, um den Starttyp zu ändern.

z.

sc config yourservicename start=auto 

Oder Sie können ChangeServiceConfig verwenden.

+0

Danke, aber der Starttyp scheint nach dem Abschluss der Installation automatisch zu sein. Also, keine Notwendigkeit, es zu ändern. Außerdem werden die Benutzer niemals einen Befehl ausführen. –

+0

@OrkunBekar Wenn der Starttyp automatisch ist, nachdem der Windows-Neustart-Dienst gestartet werden muss, aber es aus irgendeinem Grund fehlschlägt, sehen Sie sich EventLog für Dienstfehler an. – BWA

+0

@orkunbekar Wenn der Starttyp auf automatisch eingestellt ist, wird er automatisch beim Neustart gestartet. Aber das Festlegen des Starttyps auf auto bedeutet nicht "sofort starten". Sie müssen den ersten Start manuell durchführen. Es bedeutet auch nicht "Neustart, nachdem es gestoppt/abgestürzt ist", es gibt separate Einstellungen dafür. – derpirscher

1

Sie können dies einfacher machen, indem Sie das NuGet-Paket mit der Bezeichnung TopShelf herunterladen.

kurz zusammenfassen, unter Angabe von ihren page:

Topshelf ist ein Framework für Dienste geschrieben mit .NET Rahmen Hosting. Die Erstellung von Diensten wird vereinfacht, sodass die Entwickler eine einfache Konsolenanwendung erstellen können, die als ein Dienst unter Verwendung von Topshelf installiert werden kann. Der Grund dafür ist einfach: Es ist weit einfacher, eine Konsolenanwendung als ein Dienst zu debuggen. Und sobald die Anwendung getestet und bereit für die Produktion ist, macht es Topshelf einfach, die Anwendung als Dienst zu installieren.

Verwandte Themen