Comment faire pour qu’un service Windows .NET démarre juste après l’installation?

Outre le service.StartType = ServiceStartMode.Automatic mon service ne démarre pas après l’installation

Solution

Inséré ce code sur mon ProjectInstaller

protected override void OnAfterInstall(System.Collections.IDictionary savedState) { base.OnAfterInstall(savedState); using (var serviceController = new ServiceController(this.serviceInstaller1.ServiceName, Environment.MachineName)) serviceController.Start(); } 

Merci à ScottTx et Francis B.

Vous pouvez le faire à partir de votre exécutable de service en réponse aux événements déclenchés à partir du processus InstallUtil. Remplacez l’événement OnAfterInstall pour utiliser une classe ServiceController pour démarrer le service.

http://msdn.microsoft.com/en-us/library/system.serviceprocess.serviceinstaller.aspx

J’ai posté une procédure pas à pas pour créer un service Windows en C # ici . On dirait que vous êtes au moins à ce point, et maintenant vous vous demandez comment démarrer le service une fois qu’il est installé. Si vous définissez la propriété StartType sur Automatique, le service démarrera automatiquement après le redémarrage de votre système, mais il ne démarrera pas automatiquement (comme vous l’avez découvert) après l’installation.

Je ne me souviens pas où je l’ai trouvé à l’origine (peut-être Marc Gravell?), Mais j’ai trouvé une solution en ligne qui vous permet d’installer et de démarrer votre service en exécutant réellement votre service lui-même. Voici l’étape par étape:

  1. Structurez la fonction Main() de votre service comme ceci:

     static void Main(ssortingng[] args) { if (args.Length == 0) { // Run your service normally. ServiceBase[] ServicesToRun = new ServiceBase[] {new YourService()}; ServiceBase.Run(ServicesToRun); } else if (args.Length == 1) { switch (args[0]) { case "-install": InstallService(); StartService(); break; case "-uninstall": StopService(); UninstallService(); break; default: throw new NotImplementedException(); } } } 
  2. Voici le code support:

     using System.Collections; using System.Configuration.Install; using System.ServiceProcess; private static bool IsInstalled() { using (ServiceController controller = new ServiceController("YourServiceName")) { try { ServiceControllerStatus status = controller.Status; } catch { return false; } return true; } } private static bool IsRunning() { using (ServiceController controller = new ServiceController("YourServiceName")) { if (!IsInstalled()) return false; return (controller.Status == ServiceControllerStatus.Running); } } private static AssemblyInstaller GetInstaller() { AssemblyInstaller installer = new AssemblyInstaller( typeof(YourServiceType).Assembly, null); installer.UseNewContext = true; return installer; } 
  3. En continuant avec le code de support …

     private static void InstallService() { if (IsInstalled()) return; try { using (AssemblyInstaller installer = GetInstaller()) { IDictionary state = new Hashtable(); try { installer.Install(state); installer.Commit(state); } catch { try { installer.Rollback(state); } catch { } throw; } } } catch { throw; } } private static void UninstallService() { if ( !IsInstalled() ) return; try { using ( AssemblyInstaller installer = GetInstaller() ) { IDictionary state = new Hashtable(); try { installer.Uninstall( state ); } catch { throw; } } } catch { throw; } } private static void StartService() { if ( !IsInstalled() ) return; using (ServiceController controller = new ServiceController("YourServiceName")) { try { if ( controller.Status != ServiceControllerStatus.Running ) { controller.Start(); controller.WaitForStatus( ServiceControllerStatus.Running, TimeSpan.FromSeconds( 10 ) ); } } catch { throw; } } } private static void StopService() { if ( !IsInstalled() ) return; using ( ServiceController controller = new ServiceController("YourServiceName")) { try { if ( controller.Status != ServiceControllerStatus.Stopped ) { controller.Stop(); controller.WaitForStatus( ServiceControllerStatus.Stopped, TimeSpan.FromSeconds( 10 ) ); } } catch { throw; } } } 
  4. À ce stade, après avoir installé votre service sur l’ordinateur cible, exécutez simplement votre service à partir de la ligne de commande (comme toute application ordinaire) avec l’argument de ligne de commande -install pour installer et démarrer votre service.

Je pense avoir tout couvert, mais si vous trouvez que cela ne fonctionne pas, faites-le moi savoir pour que je puisse mettre à jour la réponse.

Visual Studio

Si vous créez un projet d’installation avec VS, vous pouvez créer une action personnalisée qui a appelé une méthode .NET pour démarrer le service. Mais, il n’est pas vraiment recommandé d’utiliser une action personnalisée gérée dans un fichier MSI. Voir cette page

 ServiceController controller = new ServiceController(); controller.MachineName = "";//The machine where the service is installed; controller.ServiceName = "";//The name of your service installed in Windows Services; controller.Start(); 

InstallShield ou Wise

Si vous utilisez InstallShield ou Wise, ces applications offrent la possibilité de démarrer le service. Par exemple avec Wise, vous devez append une action de contrôle de service. Dans cette action, vous spécifiez si vous souhaitez démarrer ou arrêter le service.

Wix

En utilisant Wix, vous devez append le code xml suivant sous le composant de votre service. Pour plus d’informations à ce sujet, vous pouvez consulter cette page .

   ///Add any dependancy to your service  

Vous devez append une action personnalisée à la fin de la séquence ‘ExecuteImmediate’ dans le fichier MSI, en utilisant le nom du composant EXE ou un lot (sc start) comme source. Je ne pense pas que cela puisse être fait avec Visual Studio, vous devrez peut-être utiliser un véritable outil de création MSI pour cela.

Pour le démarrer juste après l’installation, je génère un fichier de commandes avec installutil suivi de sc start

Ce n’est pas idéal, mais ça marche …

Utilisez la classe .NET ServiceController pour la démarrer ou exécutez la commande commandline pour la lancer — “net start servicename”. De toute façon fonctionne.

Pour append à la réponse de ScottTx, voici le code réel pour démarrer le service si vous le faites à la manière de Microsoft (par exemple, en utilisant un projet d’installation, etc.).

(excusez le code VB.net, mais c’est ce que je suis coincé)

 Private Sub ServiceInstaller1_AfterInstall(ByVal sender As System.Object, ByVal e As System.Configuration.Install.InstallEventArgs) Handles ServiceInstaller1.AfterInstall Dim sc As New ServiceController() sc.ServiceName = ServiceInstaller1.ServiceName If sc.Status = ServiceControllerStatus.Stopped Then Try ' Start the service, and wait until its status is "Running". sc.Start() sc.WaitForStatus(ServiceControllerStatus.Running) ' TODO: log status of service here: sc.Status Catch ex As Exception ' TODO: log an error here: "Could not start service: ex.Message" Throw End Try End If End Sub 

Pour créer le gestionnaire d’événement ci-dessus, accédez au concepteur ProjectInstaller où se trouvent les 2 contrôleurs. Cliquez sur le contrôle ServiceInstaller1. Accédez à la fenêtre des propriétés sous les événements et vous y trouverez l’événement AfterInstall.

Remarque: Ne placez pas le code ci-dessus sous l’événement AfterInstall pour ServiceProcessInstaller1. Cela ne marchera pas, venant de l’expérience. 🙂

La solution la plus simple est trouvée ici install-windows-service-sans-installutil-exe par @ Hoàng Long

 @echo OFF echo Stopping old service version... net stop "[YOUR SERVICE NAME]" echo Uninstalling old service version... sc delete "[YOUR SERVICE NAME]" echo Installing service... rem DO NOT remove the space after "binpath="! sc create "[YOUR SERVICE NAME]" binpath= "[PATH_TO_YOUR_SERVICE_EXE]" start= auto echo Starting server complete pause