Gerer les services de windows avec winsvc

Soyez le premier à donner votre avis sur cette source.

Vue 11 985 fois - Téléchargée 1 334 fois

Description

Ce matin par MP quelqu'un m'a demandé comment contrôler les services de Windows.
Voilà donc un petit exemple "très succint" de certaines fonctionalités de la librairie WinSVC, fourni avec Delphi. Cette librairie permet d'accéder à différentes API Windows permettant la gestion des services Windows.

Possibilité dans cette source de définir une application comme service.
Detruire un service.
Démarrer et arreter un service.

Et tous ceci sur une machine distante si vous le souhaitez.

Source / Exemple :


{

  • ----------------------------------------------*
Exemple d'utilisation de la librairie WinSVC et des services Windows. Par LEVEUGLE Damien (c) 2006 Pour Code-Source / DelphiFr.Com
  • ----------------------------------------------*
Unité à complété et à finir ! } unit ElgServiceNT; {.DATA} interface uses Windows, WinSVC; function ServiceCreate( SrvName : string; Libelle : string; Chemin : string; Machine : string = '' ) : Boolean; // function ServiceOpen( SrvName : string; Machine : string = '' ) : Cardinal; function ServiceRemove( SrvName : string; Machine : string = '' ) : Boolean; function ServiceStart ( SrvName : string; Machine : string = '' ) : Boolean; function ServiceStop ( SrvName : string; Machine : string = '' ) : Boolean; function ServiceState ( SrvName : string; Machine : string = '' ) : string; {.CODE} implementation { Ouvre un service } function ServiceOpen( SrvName : string; Machine : string = '' ) : Cardinal; var H_SC : SC_Handle; begin if ( Machine = '' ) then H_SC := OpenSCManager( nil, nil, SC_MANAGER_ALL_ACCESS ) else H_SC := OpenSCManager( PChar( Machine ), nil, SC_MANAGER_ALL_ACCESS ); Result := OpenService( H_SC, PChar( SrvName ), SC_MANAGER_ALL_ACCESS ); end; { Créé un service } function ServiceCreate( SrvName : string; Libelle : string; Chemin : string; Machine : string = '' ) : Boolean; var H_SC : SC_Handle; H_Sr : SC_Handle; begin Result := False; H_SC := ServiceOpen( SrvName, Machine ); if ( H_SC > 0 ) then begin H_Sr := CreateService( H_SC, PChar( SrvName ), PChar( Libelle ), SC_MANAGER_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, PChar( Chemin ), nil, nil, nil, nil, nil ); if ( H_Sr > 0 ) then Result := True else begin MessageBoxA( 0, PChar( 'Une erreur c''est produite à la création du service' ), PChar('Erreur'), MB_ICONWARNING ); Result := False end; CloseServiceHandle(H_Sr); CloseServiceHandle(H_SC); end; end; { Supprime un service } function ServiceRemove( SrvName : string; Machine : string = '' ) : Boolean; var SrvHandle : Cardinal; begin Result := False; SrvHandle := ServiceOpen( SrvName, Machine ); try Result := DeleteService( SrvHandle ); finally CloseServiceHandle( SrvHandle ); end; end; { Démarre un service } function ServiceStart( SrvName : string; Machine : string = '' ) : Boolean; var SrvHandle : Cardinal; ServiceArgVectors : PAnsiChar; SrvState : _SERVICE_STATUS; begin Result := False; ServiceArgVectors := nil; SrvHandle := ServiceOpen( SrvName, Machine ); try Result := ( StartService( SrvHandle, 0, ServiceArgVectors ) ); finally CloseServiceHandle( SrvHandle ); end; end; { Arrête un service } function ServiceStop( SrvName : string; Machine : string = '' ) : Boolean; var SrvHandle : Cardinal; ServiceArgVectors : PAnsiChar; SrvState : _SERVICE_STATUS; begin Result := False; ServiceArgVectors := nil; SrvHandle := ServiceOpen( SrvName, Machine ); try Result := ControlService( SrvHandle, SERVICE_CONTROL_STOP, SrvState ); (* Si çà vous interesse, les différents autres status sont : - SERVICE_CONTROL_STOP - SERVICE_CONTROL_PAUSE - SERVICE_CONTROL_CONTINUE - SERVICE_CONTROL_INTERROGATE - SERVICE_CONTROL_SHUTDOWN
  • )
finally CloseServiceHandle( SrvHandle ); end; end; { Renvoi l'etat actuel du service } function ServiceState( SrvName : string; Machine : string = '' ) : string; var SrvHandle : Cardinal; SrvState : _SERVICE_STATUS; begin SrvHandle := ServiceOpen( SrvName, Machine ); try if not ( QueryServiceStatus( SrvHandle, SrvState ) ) then Result := 'Le service est inexistant !' else begin case ( SrvState.dwCurrentState ) of SERVICE_CONTINUE_PENDING : Result := 'Le service est en train d''être relancé après une opération continue'; SERVICE_PAUSE_PENDING : Result := 'le service est en train d''être relancé après une opération pause'; SERVICE_PAUSED : Result := 'Le service est en pause'; SERVICE_RUNNING : Result := 'Le service est démarré'; SERVICE_START_PENDING : Result := 'Le service est en cours de démarrage'; SERVICE_STOP_PENDING : Result := 'Le service est en cours d''arrêt'; SERVICE_STOPPED : Result := 'Le service est stoppé'; else Result := 'Etat du service inconnu ou service inexistant !'; end; end; finally CloseServiceHandle( SrvHandle ); end; end; end.

Conclusion :


Notes, questions, commentaires, et insultes sont les bienvenus !

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
6
Date d'inscription
jeudi 1 février 2007
Statut
Membre
Dernière intervention
29 août 2008

En effet. il faut faire la modif de jojoprout dans ServiceCreate si non, ca ne fonctionne pas.
Messages postés
5
Date d'inscription
samedi 10 janvier 2004
Statut
Membre
Dernière intervention
26 décembre 2007

Bonjour.
Le code est génial pour le pc local mais ne fonctionne pas sur un pc sur le réseau local...
Pourquoi ??
Messages postés
106
Date d'inscription
mardi 18 juin 2002
Statut
Membre
Dernière intervention
13 janvier 2007

simple et pratique
Messages postés
3
Date d'inscription
vendredi 20 octobre 2006
Statut
Membre
Dernière intervention
8 décembre 2006

Me revoici me revoila...

Je te propose une function complémentaire à ton unité ElgServiceNT, une fonction permettant d'indiquer la description du service. Pour ce faire, il nous faut au préalable ajouter une unité supplémentaire permettant de combler un oubli(?) dans l'unité WinSvc. En effet, la function permettant de faire la description du service est ChangeServiceConfig2 et elle ne s'y trouve pas dans WinSvc.

Voici la nouvelle unité :

unit WinSVC_fragment;

interface

uses WinSVC, Windows;

function ChangeServiceConfig2A(hService: SC_HANDLE; dwInfoLevel: DWord;
lpInfo: Pointer): BOOL; stdcall;
function ChangeServiceConfig2W(hService: SC_HANDLE; dwInfoLevel: DWord;
lpInfo: Pointer): BOOL; stdcall;
function ChangeServiceConfig2(hService: SC_HANDLE; dwInfoLevel: DWord;
lpInfo: Pointer): BOOL; stdcall;

type
_SERVICE_DESCRIPTIONA = packed record
lpDescription: PChar;
end;
TServiceDescriptionA = _SERVICE_DESCRIPTIONA;
PServiceDescriptionA = ^TServiceDescriptionA;

_SERVICE_DESCRIPTIONW = packed record
lpDescription: PWChar;
end;
TServiceDescriptionW = _SERVICE_DESCRIPTIONW;
PServiceDescriptionW = ^TServiceDescriptionW;

//we use the ANSI version
TServiceDescription = TServiceDescriptionA;

const
SERVICE_CONFIG_DESCRIPTION = 1;
SERVICE_CONFIG_FAILURE_ACTIONS = 2;

implementation

function ChangeServiceConfig2A; external advapi32 name 'ChangeServiceConfig2A';
function ChangeServiceConfig2W; external advapi32 name 'ChangeServiceConfig2W';
function ChangeServiceConfig2; external advapi32 name 'ChangeServiceConfig2A';

end.

...la nouvelle function dans ton unité :

{ajoute une description du service}
function ServiceDescription(const Value: String; SrvName : string; Machine : string = '') : Boolean;
var
sd: TServiceDescription;
SrvHandle : Cardinal;
begin
SrvHandle := ServiceOpen( SrvName, Machine );
sd.lpDescription := PChar(Value);
try
result := ChangeServiceConfig2(SrvHandle, SERVICE_CONFIG_DESCRIPTION, @sd);
finally
CloseServiceHandle( SrvHandle );
end;
end;

...ne pas oublier bien entendu de rajouter
dans la partie uses WinSvc_fragment.

Cette nouvelle function s'utilisera comme les précédentes...

PS : je l'ai testé et ô miracle ça marche !
Messages postés
718
Date d'inscription
jeudi 19 décembre 2002
Statut
Membre
Dernière intervention
22 novembre 2016
3
Ah mais oui je vois le problème ... tu as tout a fait raison.

En fait j'avais crée ma fonction "ServiceOpen" pour evité d'avoir à faire mon "H_SC := OpenSCManager( nil, nil, SC_MANAGER_ALL_ACCESS )" à chaque fonction (create, remove, etcc...) mais effectivement pour le create çà ne marche pas car comme tu le dis si bien ... on ne peux pas ouvrir un service qui n'a pas encore été crée :-)

Bien vu ;-)

Merci, et je corrigerai çà dès que possible (oula j'ai de plus en plus de boulot là)
Afficher les 19 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.