elguevel
Messages postés718Date d'inscriptionjeudi 19 décembre 2002StatutMembreDernière intervention22 novembre 2016
-
21 nov. 2006 à 16:31
becauet
Messages postés6Date d'inscriptionjeudi 1 février 2007StatutMembreDernière intervention29 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.
becauet
Messages postés6Date d'inscriptionjeudi 1 février 2007StatutMembreDernière intervention29 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és5Date d'inscriptionsamedi 10 janvier 2004StatutMembreDernière intervention26 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és106Date d'inscriptionmardi 18 juin 2002StatutMembreDernière intervention13 janvier 2007 23 juin 2007 à 20:32
simple et pratique
jojoprout
Messages postés3Date d'inscriptionvendredi 20 octobre 2006StatutMembreDerniè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;
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és718Date d'inscriptionjeudi 19 décembre 2002StatutMembreDernière intervention22 novembre 20163 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és3Date d'inscriptionvendredi 20 octobre 2006StatutMembreDerniè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és718Date d'inscriptionjeudi 19 décembre 2002StatutMembreDernière intervention22 novembre 20163 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és718Date d'inscriptionjeudi 19 décembre 2002StatutMembreDernière intervention22 novembre 20163 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és3Date d'inscriptionvendredi 20 octobre 2006StatutMembreDerniè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és106Date d'inscriptionmardi 18 juin 2002StatutMembreDernière intervention13 janvier 2007 23 nov. 2006 à 20:28
Source interessant, bravo.
taye78
Messages postés106Date d'inscriptionmardi 18 juin 2002StatutMembreDernière intervention13 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és718Date d'inscriptionjeudi 19 décembre 2002StatutMembreDernière intervention22 novembre 20163 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...
Où encore "Menu Demarrer" --> "Executer" --> "services.msc /s"
elguevel
Messages postés718Date d'inscriptionjeudi 19 décembre 2002StatutMembreDernière intervention22 novembre 20163 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és4720Date d'inscriptiondimanche 26 février 2006StatutModérateurDernière intervention31 juillet 202113 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és718Date d'inscriptionjeudi 19 décembre 2002StatutMembreDernière intervention22 novembre 20163 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és4720Date d'inscriptiondimanche 26 février 2006StatutModérateurDernière intervention31 juillet 202113 21 nov. 2006 à 19:03
un petite demo ça serait sympa..
merci
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201332 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és718Date d'inscriptionjeudi 19 décembre 2002StatutMembreDernière intervention22 novembre 20163 21 nov. 2006 à 16:31
6 mai 2008 à 19:01
26 déc. 2007 à 15:49
Le code est génial pour le pc local mais ne fonctionne pas sur un pc sur le réseau local...
Pourquoi ??
23 juin 2007 à 20:32
8 déc. 2006 à 21:55
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 !
7 déc. 2006 à 15:33
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à)
7 déc. 2006 à 15:23
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.
7 déc. 2006 à 13:14
Donc oublie le premier paragraphe de mon commentaire precedant.
Par contre l'histoire du "OpenService" tiens toujours :-)
7 déc. 2006 à 13:00
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!
6 déc. 2006 à 21:47
23 nov. 2006 à 20:28
23 nov. 2006 à 20:28
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
23 nov. 2006 à 15:26
On peut aussi passer par le menu démarrer et aller dans Outils d'administration > Services...
Enfin les liens ne manquent pas.
Merci ;-)
23 nov. 2006 à 14:36
Où encore "Menu Demarrer" --> "Executer" --> "services.msc /s"
22 nov. 2006 à 08:51
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"
21 nov. 2006 à 22:20
l'intérêt c'est la machine distante..
mais comme delphiProg, et si tout est verrouillé ?
21 nov. 2006 à 20:20
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.
21 nov. 2006 à 19:03
merci
21 nov. 2006 à 18:25
Question : ce code fonctionne-t-il aussi avec des droits restreints ?
21 nov. 2006 à 16:31
Vous y trouverez toute l'aide necessaire.