GERER LES SERVICES DE WINDOWS AVEC WINSVC

elguevel Messages postés 718 Date d'inscription jeudi 19 décembre 2002 Statut Membre Dernière intervention 22 novembre 2016 - 21 nov. 2006 à 16:31
becauet Messages postés 6 Date d'inscription jeudi 1 février 2007 Statut Membre Dernière intervention 29 août 2008 - 6 mai 2008 à 19:01
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/40408-gerer-les-services-de-windows-avec-winsvc

becauet Messages postés 6 Date d'inscription jeudi 1 février 2007 Statut Membre Dernière intervention 29 août 2008
6 mai 2008 à 19:01
En effet. il faut faire la modif de jojoprout dans ServiceCreate si non, ca ne fonctionne pas.
bhf37 Messages postés 5 Date d'inscription samedi 10 janvier 2004 Statut Membre Dernière intervention 26 décembre 2007
26 déc. 2007 à 15:49
Bonjour.
Le code est génial pour le pc local mais ne fonctionne pas sur un pc sur le réseau local...
Pourquoi ??
taye78 Messages postés 106 Date d'inscription mardi 18 juin 2002 Statut Membre Dernière intervention 13 janvier 2007
23 juin 2007 à 20:32
simple et pratique
jojoprout Messages postés 3 Date d'inscription vendredi 20 octobre 2006 Statut Membre Dernière intervention 8 décembre 2006
8 déc. 2006 à 21:55
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 !
elguevel Messages postés 718 Date d'inscription jeudi 19 décembre 2002 Statut Membre Dernière intervention 22 novembre 2016 3
7 déc. 2006 à 15:33
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à)
jojoprout Messages postés 3 Date d'inscription vendredi 20 octobre 2006 Statut Membre Dernière intervention 8 décembre 2006
7 déc. 2006 à 15:23
Désolé de te contredire, mais ma modif tient toujours, car avec ta function ServiceOpen, tu essaies d'ouvrir un service qui n'existe pas encore. Donc, deux solutions, soit directement passer par H_SC := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS); dans la function ServiceCreate ou modifier ta function ServiceOpen comme ceci :
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 );

if ( SrvName = '' ) then
result := H_SC
else
Result := OpenService( H_SC,
PChar( SrvName ),
SC_MANAGER_ALL_ACCESS );
end;
... et dans la function ServiceCreate , modifier la ligne H_SC := ServiceOpen( SrvName, Machine ); par H_SC := ServiceOpen( '', Machine );

Je ne suis qu'un débutant, mais mes tests le prouvent et d'ailleurs dans la SDK Windows il est dit de passer direct par OpenSCManager sans passer par OpenService.
elguevel Messages postés 718 Date d'inscription jeudi 19 décembre 2002 Statut Membre Dernière intervention 22 novembre 2016 3
7 déc. 2006 à 13:14
Ah mais M****, j'me suis complétement trompé de source, je penssais que tu me parlais d'une autre ... méa culpa.

Donc oublie le premier paragraphe de mon commentaire precedant.

Par contre l'histoire du "OpenService" tiens toujours :-)
elguevel Messages postés 718 Date d'inscription jeudi 19 décembre 2002 Statut Membre Dernière intervention 22 novembre 2016 3
7 déc. 2006 à 13:00
Je vais me faire lincher si je dis çà, mais je n'ai même pas testé mon application. J'ai repris un ancien code auquel j'ai ajouté cette histoire de service et d'acces au registre distant, mais ayant codé çà au boulot un matin, j'ai pas voulu tester çà sur place, d'autant que je ne possède pas de droit suffisants.

Sinon merci d'avoir testé l'application, mais ta correction n'est pas juste puisque [ ServiceOpen( SrvName, Machine ); ] est une fonction que j'ai crée et qui appelle bien [OpenSCManager].


{ 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;

Tu doit confondre mon "ServiceOpen" avec l'API "OpenService" !


PS : Promis dès que j'aurai le temps, j'ferai un truc plus propre !

Merci, et bon code!
jojoprout Messages postés 3 Date d'inscription vendredi 20 octobre 2006 Statut Membre Dernière intervention 8 décembre 2006
6 déc. 2006 à 21:47
Une petite correction au niveau de la function ServiceCreate : remplacer la ligne 57 [ H_SC := ServiceOpen( SrvName, Machine ); ] par [ H_SC := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS); ], car la function CreateService de l'API winsvc suppose que le Handle ait été ouvert par OpenSCManager. J'avoue que j'ai mis un peu de temps avant de comprendre l'erreur ! Pour le reste, tout fonctionne, si ce n'est la fermeture du service où je suis obligé de lancer pour certains services 2 fois un ServiceStop : pb de tempo ?
taye78 Messages postés 106 Date d'inscription mardi 18 juin 2002 Statut Membre Dernière intervention 13 janvier 2007
23 nov. 2006 à 20:28
Source interessant, bravo.
taye78 Messages postés 106 Date d'inscription mardi 18 juin 2002 Statut Membre Dernière intervention 13 janvier 2007
23 nov. 2006 à 20:28
Je n'ai pas regardé le source mais comme la régle est la même pour tous:
Sans droit administrateur l'utilisateur n'aura pas accès a l'administration des services.
Pour que le programme ait accès aux APIs win32(ou natives évidement) d'administration de service, il devra être lancé a partir d'un utilisateur avec les droits necessaires ou les obtenir par divers méthodes/APIs:
User interactif, LogonUser, ImpersonateLoggedOnUser (utiliser les droits (ACL etc) d'un utilisateur déjà loggé et opérer grace a eux), CreateProcessAsUser etc... et j'en passe
elguevel Messages postés 718 Date d'inscription jeudi 19 décembre 2002 Statut Membre Dernière intervention 22 novembre 2016 3
23 nov. 2006 à 15:26
Tout à fait c'est beaucoup plus direct, mais neamoins il faut se souvenir de la commande MMC :-)

On peut aussi passer par le menu démarrer et aller dans Outils d'administration > Services...

Enfin les liens ne manquent pas.

Merci ;-)
Utilisateur anonyme
23 nov. 2006 à 14:36
Salut,

Où encore "Menu Demarrer" --> "Executer" --> "services.msc /s"
elguevel Messages postés 718 Date d'inscription jeudi 19 décembre 2002 Statut Membre Dernière intervention 22 novembre 2016 3
22 nov. 2006 à 08:51
Si tout est verouillé, alors il faut trouver une autre méthode... IPC, mailslot.. il doit bien y avoir un moyen, mais certainement bcp plus compliqué a mettre en oeuvre, surtout si il y à une verification des droits.

Et je viens de m'appercevoir que j'ai ecris une grosse connerie, donc je corrige, pour voir vos services, faite :
Bouton Droit sur le "Poste de travail" > "Gérer" > "Service et Application" > "Services"
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
21 nov. 2006 à 22:20
j'ai tout lu et c'est good.
l'intérêt c'est la machine distante..
mais comme delphiProg, et si tout est verrouillé ?
elguevel Messages postés 718 Date d'inscription jeudi 19 décembre 2002 Statut Membre Dernière intervention 22 novembre 2016 3
21 nov. 2006 à 20:20
J'ai posté la source assez rapidement, mais elle n'est pas vraiment terminée... il reste encore à faire.

Sinon non, le défaut des API est qu'elles sont soumises aux droits qu'à l'utilisateur.

Sinon CANTADOR ... qu'attends tu comme démo ? Le programme est là pour çà !

Pour visualiser vos services, faites bouton droit sur le poste de travail > propriété > et dans la console MMC chercher Services (en bas). Voila vous pourrez comparer par vous même.

Merci.
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
21 nov. 2006 à 19:03
un petite demo ça serait sympa..
merci
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
21 nov. 2006 à 18:25
Code très intéressant. Merci de nous le faire partager.

Question : ce code fonctionne-t-il aussi avec des droits restreints ?
elguevel Messages postés 718 Date d'inscription jeudi 19 décembre 2002 Statut Membre Dernière intervention 22 novembre 2016 3
21 nov. 2006 à 16:31
Ah oui j'ai oublier de citer le site qui ma servie de reférence : http://www.developpez.com/delphi/faq/?page=services-nt

Vous y trouverez toute l'aide necessaire.
Rejoignez-nous