52 votes

Comment démarrer automatiquement votre service après l'installation ?

Comment démarrer automatiquement un service après avoir exécuté une installation à partir d'un projet de configuration de Visual Studio ?

Je viens de trouver la réponse à cette question et j'ai pensé la partager pour le bien de tous. La réponse suivra. Je suis ouvert à d'autres et meilleures façons de faire.

2 votes

Je suis ravi de voir quelqu'un poster une question utile dont il connaît la réponse. Parfois, vous savez simplement que votre conseil sera le bienvenu. Il est également possible que quelqu'un réponde en proposant une alternative intéressante à votre solution.

0 votes

C'est exactement ce que j'espère.

1 votes

C'est une chose tellement évidente à vouloir faire. Je ne cesse d'être étonné par les choses que Microsoft laisse de côté dans son code.

56voto

Jason Z Points 5135

Ajoutez la classe suivante à votre projet.

using System.ServiceProcess;  

class ServInstaller : ServiceInstaller
{
    protected override void OnCommitted(System.Collections.IDictionary savedState)
    {
        ServiceController sc = new ServiceController("YourServiceNameGoesHere");
        sc.Start();
    }
}

Le projet d'installation récupérera la classe et exécutera votre service après la fin du programme d'installation.

3 votes

ServiceController implémente IDisposable. Le fait de ne pas utiliser le mot clé "using" ou de ne pas appeler la méthode Dispose était-il intentionnel ?

0 votes

Je suis d'accord pour dire que c'est toujours une bonne idée de s'en débarrasser correctement. Dans ce cas, il ne s'exécute qu'une fois. Le OnCommitted se déclenche après l'exécution du programme d'installation, puis le service est géré comme n'importe quel autre et démarre automatiquement au prochain redémarrage.

7 votes

Qu'en est-il de base.OnCommitted(...). Doit-on l'appeler ?

41voto

andnil Points 8179

Petit ajout à la réponse acceptée :

Vous pouvez également récupérer le nom du service de cette façon - évitant ainsi tout problème si le nom du service est modifié à l'avenir :

protected override void OnCommitted(System.Collections.IDictionary savedState)
{
    new ServiceController(serviceInstaller1.ServiceName).Start();
}

(Chaque installateur possède un ServiceProcessInstaller et un ServiceInstaller. Ici, le ServiceInstaller est appelé ServiceInstaller1).

0 votes

ServiceInstaller1 est une variable membre privée de ProjectInstaller, alors comment puis-je y accéder à partir de ServInstaller ?

24voto

Keith Points 5138

Cette approche utilise la classe Installer et la plus petite quantité de code.

using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace MyProject
{
    [RunInstaller(true)]
    public partial class ProjectInstaller : Installer
    {
        public ProjectInstaller()
        {
            InitializeComponent();
            serviceInstaller1.AfterInstall += (sender, args) => new ServiceController(serviceInstaller1.ServiceName).Start();
        }
    }
}

Définir serviceInstaller1 (de type ServiceInstaller) dans le concepteur de la classe Installer et définir également son ServiceName dans le concepteur.

0 votes

Je dois mettre ce code dans l'événement Committed à la place. Il semble que mon service n'est pas encore disponible OnAfterInstall.

10voto

Merci, il fonctionne bien...

private System.ServiceProcess.ServiceInstaller serviceInstaller1;

private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e)
{
    ServiceController sc = new ServiceController("YourServiceName");
    sc.Start();
}

7voto

HeWillem Points 337

Au lieu de créer votre propre classe, sélectionnez l'installateur de service dans l'installateur de projet et ajoutez un gestionnaire d'événement à l'événement Comitted :

private void serviceInstallerService1_Committed(object sender, InstallEventArgs e)
{
    var serviceInstaller = sender as ServiceInstaller;
    // Start the service after it is installed.
    if (serviceInstaller != null && serviceInstaller.StartType == ServiceStartMode.Automatic)
    {
        var serviceController = new ServiceController(serviceInstaller.ServiceName);
        serviceController.Start();
    }
}

Il ne démarrera votre service que si le type de démarrage est réglé sur automatique.

0 votes

N'oubliez pas d'ajouter : using System.ServiceProcess;

0 votes

C'est l'option qui a le mieux fonctionné pour moi et qui semble la plus simple et la plus évidente.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X