Besoin d’un Service Windows : Optez pour TopShelf

Les services Windows sont souvent délaissés car l’on imagine toujours à quel point le déploiement risque d’être compliqué. Et pourtant, ce type de composant peut se révéler extrêmement efficace pour traiter nombre d’opérations en arrière-plan. Nous allons voir, dans cet article, comment simplifier de manière significative la phase d’installation mais également celle d’implémentation en utilisant une librairie : TopShelf.
Setup du projet
La première étape consiste à créer un projet console à l’aide de Visual Studio. Ensuite, il faut ajouter la liste des dépendances externes via NuGet. Pour cet exemple, j’ai choisi d’ajouter le support de log4net et de SimpleInjector.
Création du service
Passons maintenant à la création du service en lui-même. Je vous laisse découvrir le code ci-dessous permettant d’atteindre cet objectif :
static void Main(string[] args) { // Configure container var container = new Container(); container.Register<IClock, Clock>(); // Top shelf setup HostFactory.Run( config => { config.UseSimpleInjector(container); config.UseLog4Net("log4net.xml"); config.Service<Clock>( s => { s.ConstructUsingSimpleInjector(); s.WhenStarted(tc => tc.Start()); s.WhenStopped(tc => tc.Stop()); }); config.SetDescription("TopShelf Demo service"); config.SetDisplayName("TopShelf Demo"); config.SetServiceName("TopShelfDemo"); }); }
Comme vous pouvez le constater, le code est relativement simple et concis. Dans un premier temps, il faut instancier le conteneur SimpleInjector et le donner à TopShelf. La configuration de log4net est, elle aussi, très simple puisqu’elle se résume à une ligne. Ensuite, il faut déclarer quelle classe contiendra le traitement, dans notre cas : Clock. Cette dernière possède deux méthodes qui seront appelées par TopShelf : Start lors du démarrage et Stop lors de l’arrêt.
En démarrant le projet disponible sur GitHub (cf. liens ci-dessous), vous pourrez voir une console s’ouvrir et le code de la classe Clock s’exécuter. A cette étape, il n’y a toujours pas de service Windows, car il faut le déployer.
Déploiement
Ce qui est vraiment intéressant avec TopShelf, c’est qu’il s’auto-installe. Concrètement, en passant différents paramètres à l’exécutable généré, vous pourrez, au choix, installer/démarrer/désinstaller le service. Pour illustrer ce propos, voici un script powershell permettant d’installer le service :
./TopShelf.Demo.exe uninstall echo "Uninstall done" ./TopShelf.Demo.exe install ./TopShelf.Demo.exe start echo "Install done"
Dans le projet, le script ci-dessus est exécuté en post build event lors du build. Cependant, pour que la compilation se déroule correctement, il faut que le service soit stoppé au préalable. Voici donc le script à exécuter en pré build event :
$name = "TopShelf Demo" $service = Get-Service -Name $name -ErrorAction SilentlyContinue if ($service.Length -gt 0 -and $service.Status -eq 'Running') { # If we don't stop the service, the build process will fail # because files are locked echo "Stopping service" $name Stop-Service -Name $name -ErrorAction SilentlyContinue }
Liens
Conclusion
Si vous envisagez la création d’un service autonome, TopShelf est vraiment une librairie qui vous fera gagner du temps et vous simplifiera les procédures de déploiements. De plus, l’intégration avec de nombreuses librairies permettra de répondra à un large éventail de besoins.