[Windows 7] Gestion des services triggers-started via PInvoke
L’une des nouveautés de Windows 7 est la possibilité de lancer un service Windows sur trigger, c’est à dire lorsqu’un événement particulier se produit (insertion d’un périphérique USB, obtention/perte d’une adresse IP etc…).
Il existe plusieurs techniques permettant de gérer ce type de service, qui d’un point de vue programmatique ne sont en rien différents des services que vous avez peut-être l’habitude de développer.
J’ai développé un librairie permettant de contrôler ce type de service directement depuis du code C#. Cette librairie réalise tout simplement du PInvoke sur l’API Win32.
Pour l’instant, la classe ServiceControl (cf définition ci-dessous) permet :
- L’installation d’un service
- La suppression d’un service
- Le démarrage d’un service
- De savoir si un service est déjà installé
- De savoir si un service est lancé sur trigger
- De configurer un service pour qu’il soit démarré lors de l’obtention de la première IP, et arrêté lors de la perte de la dernière IP.
Voici le corps de la classe “ServiceControl” :
/// <summary>
/// Classe statique encapsulant des fonctions de l'API Win32 permettant de contrôler les services
/// sur une machine
/// </summary>
public static class ServiceControl
{
/// <summary>
/// Permet d'installer un service sur la machine
/// </summary>
/// <param name="serviceName">Nom du service</param>
/// <param name="displayName">Nom d'affichage du service dans la console de gestion des services Windows</param>
/// <param name="path">Chemin de l'exécutable du service</param>
public static void InstallService(string serviceName, string displayName, string path)
{
}
/// <summary>
/// Permet de supprimer un service de la machine
/// </summary>
/// <param name="serviceName">Le nom du service à supprimer</param>
public static void UninstallService(string serviceName)
{
}
/// <summary>
/// Permet de savoir si un service est déjà installé sur la machine
/// </summary>
/// <param name="serviceName">Le nom du service à tester</param>
/// <returns>(true) si le service est déjà installé, (false) sinon</returns>
public static bool IsServiceAlreadyInstalled(string serviceName)
{
}
/// <summary>
/// Permet de démarrer un service
/// </summary>
/// <param name="serviceName">Le nom du service à démarrer</param>
public static void StartService(string serviceName)
{
}
/// <summary>
/// Permet d'arrêter un service
/// </summary>
/// <param name="serviceName">Le nom du service à arrêter</param>
public static void StopService(string serviceName)
{
}
/// <summary>
/// Permet de savoir si un service est démarré sur trigger
/// </summary>
/// <param name="serviceName">Le nom du service à tester</param>
/// <returns>(true) le service est démarré sur trigger, (false) sinon</returns>
public static bool IsServiceTriggerStart(string serviceName)
{
}
/// <summary>
/// Permet de définir qu'un service doit être lancé lorsque la connexion réseau est disponible
/// </summary>
/// <param name="serviceName"></param>
public static void SetServiceTriggerStartOnNetworkOnAndStopOnNetworkOff(string serviceName)
{
}
}
Pour écrire ce code j’ai bien entendu utilisé l’excellent site PInvoke.net, sauf pour les fonctions spécifiques à Windows 7 (tout ce qui tient du trigger) qui n’y sont pas encore disponibles. Pour celles-ci, je me suis débrouillé tant bien que mal avec la MSDN et le code C++ fournit par le Windows 7 Training Kit pour parvenir au même résultat.
Voici un exemple de code utilisant ma librairie :
string serviceName = "DemoService";
if (!ServiceControl.IsServiceAlreadyInstalled(serviceName))
{
ServiceControl.InstallService(
serviceName,
serviceName,
@"C:\DemoService.exe"
);
}
if (!ServiceControl.IsServiceTriggerStart(serviceName))
{
ServiceControl.SetServiceTriggerStartOnNetworkOnAndStopOnNetworkOff(serviceName);
}
J’ai pour objectifs d’étoffer cette classe afin de permettre le contrôle des différents triggers existants, à savoir :
- Disponibilité d’une adresse IP (fait)
- Modification d’une stratégie de groupe
- Modification de la configuration d’un port du firewall Windows
- Rejoindre un domaine
- Arrivée d’un périphérique (type clé usb par exemple).
Il existe un dernier type “Custom” sur lequel je ne me suis pas encore penché réellement, mais qui semble vraiment pas simple à appréhender :p
Si vous avez des remarques/critiques/suggestions, n’hésitez pas !
Source du projet : Windows7_BackgroundService_Service.zip (119,20 kb)
A bientôt 