Les services Windows représentent une composante essentielle du développement d'applications système, bien qu'ils présentent plusieurs particularités à maîtriser. Ce guide pratique se concentre sur la mise en œuvre de services Windows fondamentaux avec C#, en évitant les aspects complexes pour se concentrer sur les besoins concrets des applications.
Ce tutoriel détaille étape par étape la création, l'installation, le lancement, la survelilance et la désinstallation de services Windows simples avec C#, en mettant en avant les points critiques à ne pas négliger.
I. Création d'un projet de service Windows
- Initialisation du projet Commencez par créer un nouveau projet de type "Service Windows" dans Visual Studio.
- Renommage du service Modifiez le nom par défaut (Service1) pour un nom plus approprié, tel que MonServiceSysteme.
II. Configuration du programme d'installation
- Ajout du composant d'installation Via l'explorateur de solutions, ajoutez un nouveau composant d'installation à votre projet. Cette action générera automatiquement un fichier ProjectInstaller.cs ainsi que deux éléments d'installation.
- Personnalisation du nom du service Sélectionnez le composant serviceInstaller1, accédez à ses propriétés, et modifiez la valeur de ServiceName pour MonServiceSysteme.
- Configuration des droits d'exécution Pour le composant serviceProcessInstaller1, définissez la propriété Account sur LocalSystem afin d'assurer les permissions nécessaires.
III. Implémentation de la logique du service
- Accès au code du service Faites un clic droit sur MonServiceSysteme et choisissez "Afficher le code" pour accéder à l'éditeur.
- Développement de la fonctionnalité Intégrez le code suivant pour définir le comportement de base du service :
using System;
using System.IO;
using System.ServiceProcess;
using System.Threading;
namespace ServicesSystème
{
public class MonServiceSysteme : ServiceBase
{
private Thread _travailleur;
private bool _enExecution;
private readonly string _cheminJournal = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "service_log.txt");
public MonServiceSysteme()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
_enExecution = true;
_travailleur = new Thread(Travailleur);
_travailleur.Start();
EnregistrerEvenement("Démarrage du service");
}
protected override void OnStop()
{
_enExecution = false;
_travailleur?.Join();
EnregistrerEvenement("Arrêt du service");
}
private void Travailleur()
{
while (_enExecution)
{
EnregistrerEvenement("Service en fonctionnement");
Thread.Sleep(30000); // Exécution toutes les 30 secondes
}
}
private void EnregistrerEvenement(string message)
{
try
{
File.AppendAllText(_cheminJournal, $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}{Environment.NewLine}");
}
catch (Exception ex)
{
// Gestion basique des erreurs d'écriture
Console.WriteLine($"Erreur lors de l'écriture dans le journal : {ex.Message}");
}
}
}
}
Cette implémentation effectue un traitement périodique et consigne les événements dans un fichier journal.
IV. Mise en place des scripts d'installation
Créez deux fichiers de script dans votre projet (en utilisant l'encodage ANSI ou UTF-8 sans BOM) :
- Script d'installation : Installer.bat
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe ServicesSystème.exe
Net Start MonServiceSysteme
sc config MonServiceSysteme start= auto
- Script de désinstallation : Desinstaller.bat
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u ServicesSystème.exe
- Explication des scripts La deuxième ligne lance le service immédiatement après installation. La troisième ligne configure le service pour démarrer automatiquement au démarrage du système. Ces deux lignes sont optionnelles et dépendent des besoins spécifiques de votre service.
- Débogage des scripts Pour observer le comportement des scripts pendant leur exécution, ajoutez la commande pause à la fin du fichier.
V. Contrôle du service via une interface C#
- Structure du projet Créez une nouvelle application WPF nommée GestionServiceSysteme, et ajoutez une référence à l'assembly System.ServiceProcess. Dans le répertoire bin\Debug de votre projet WPF, créez un sous-dossier Services. Configurez les propriétés du projet de service pour que sa sortie soit placée dans ce dossier Services.
- Installation du service Le code suivant gère l'installation du service en gérant correctement le contexte du répertoire :
private void InstallerService()
{
string repertoireInitial = Environment.CurrentDirectory;
Environment.CurrentDirectory = Path.Combine(repertoireInitial, "Services");
var processus = new Process
{
StartInfo = {
FileName = "Installer.bat",
UseShellExecute = false,
CreateNoWindow = true
}
};
processus.Start();
processus.WaitForExit();
Environment.CurrentDirectory = repertoireInitial;
}
- Désinstallation du service Le processus de désinstallation nécessite une approche similaire :
private void DesinstallerService()
{
string repertoireInitial = Environment.CurrentDirectory;
Environment.CurrentDirectory = Path.Combine(repertoireInitial, "Services");
var processus = new Process
{
StartInfo = {
FileName = "Desinstaller.bat",
UseShellExecute = false,
CreateNoWindow = true
}
};
processus.Start();
processus.WaitForExit();
Environment.CurrentDirectory = repertoireInitial;
}
- Démarrage du service Voici comment lancer le service programmatiquement :
private void DemarrerService()
{
var controleurService = new ServiceController("MonServiceSysteme");
if (controleurService.Status != ServiceControllerStatus.Running)
{
controleurService.Start();
controleurService.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(30));
}
}
- Arrêt du service Pour arrêter le service proprement :
private void ArreterService()
{
var controleurService = new ServiceController("MonServiceSysteme");
if (controleurService.Status == ServiceControllerStatus.Running && controleurService.CanStop)
{
controleurService.Stop();
controleurService.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(30));
}
}
- Mise en pause/Reprise La gestion de l'état en pause :
private void GererPauseService()
{
var controleurService = new ServiceController("MonServiceSysteme");
if (controleurService.CanPauseAndContinue)
{
if (controleurService.Status == ServiceControllerStatus.Running)
controleurService.Pause();
else if (controleurService.Status == ServiceControllerStatus.Paused)
controleurService.Continue();
}
}
- Vérification de l'état Pour obtenir l'état actuel du service :
private string ObtenirEtatService()
{
var controleurService = new ServiceController("MonServiceSysteme");
return controleurService.Status switch
{
ServiceControllerStatus.Running => "En cours d'exécution",
ServiceControllerStatus.Stopped => "Arrêté",
ServiceControllerStatus.Paused => "En pause",
_ => "État inconnu"
};
}
VI. Débogage des services Windows
- Installation et exécution Installez et lancez votre service normalement.
- Attachement au processus Dans Visual Studio, allez dans le menu Déboguer > Attacher au processus, sélectionnez le processus w3wp.exe ou votre service.
- Point d'arrêt Insérez des points d'arrêt dans votre code et effectuez le débogage normalement.
VII. Considérations finales
Ce tutoriel a couvert les aspects fondamentaux de la création de services Windows avec C#. Bien que certaines configurations spécifiques n'aient pas été détaillées, cette approche permet de mettre en place rapidement des services fonctionnels répondant aux exigences professionnellles.