![]() |
Zitat:
Jetzt weiss ich es ja, Hypnose. :mrgreen: |
Zitat:
YAMM da immer offen. Hat aber keine änderungen mitbekommen. Ich musste es schliessen und wieder öffnen, dann war auch da die änderung zu sehen. Ein Schliessen und wieder öffnen des Run -Ordners hatte nichts gebracht. War es das do wie du es gedacht hattest? |
Hi Daniel.
Klingt, als würde das ME-MSCONFIG das selbe Prinzip wie unter 98 benutzen. Dass YAAM nicht auf Änderungen reagiert, liegt (programmtechnisch) auf der Hand: es ist weder Timer noch Thread drin; und ich fände es auch Quatsch, wenn er z.B. alle 10 Sekunden die Registry neu einliest. Ich habe stattdessen einen neuen Menüpunkt mit F5-Shortcut (refresh) eingefügt. :-) Für alle - Ich habe mal den aktuellen ![]() Mit voller Absicht! jetzt nicht mehr :wink: Ich bräuchte nämlich mal Rat von NT-Service-Spezialisten. Ich habe versucht, die PSDK-Beispiele zum Starten, Stoppen und Deinstallieren von Services nachzuvollziehen. Klappt prinzipiell auch. Nur diesen Part mit dem Stoppen abhängiger Services habe ich nicht so richtig gebacken bekommen. Es ist sicher das selbe Prinzip wie beim Einlesen der Services, aber wenn ich den Code übernehme, bin ich auf max. 500 Services beschränkt. Hat jemand vielleicht eine bessere Idee, wie man a) das Einlesen der Services flexibler gestalten kann, so dass man vielleicht auch 1000 Dienste einlesen kann und kein "array[0..500]of TEnumServiceStatus" mehr braucht, und b) wie man dann den Teil mit den abhängigen Services lösen kann. Wie gesagt, beim Kompilieren wird eine Fehlermeldung ausgelöst. An der Stelle müsste dann der Teil mit den "dependend services" rein. Das Einlesen mit dem genannten Array passiert übrigens in der Funktion "OpenServices". So, viel Spaß damit. Wenn ihr noch Anregungen oder so habt, dann nur her damit! ´n paar Optimierungen im Source sind sicher auch noch möglich. :wink: Gruß, Mathias. @Mods: vielleicht sollte man das Thema jetzt nach "Open Source" verschieben? |
Moin Mathias,
also zu a) habe ich eine Idee: Erstmal dafür sorgen, dass der Buffer nicht reicht, damit die Funktion die erforderliche Grösse ermittelt, und dann den Buffer entsprechend setzten. Dazu ein kurzer Ausschnitt aus einem Programm von mir, um's zu verdeutlichen:
Code:
Es gibt ja viele Funktionen, bei denen das klappt ;-)
cbBufSize := 0;
pStatus := nil; lpResumeHandle := 0; EnumServicesStatus(hSCDB,p_fType,SERVICE_STATE_ALL,pStatus,cbBufSize,@pcbBytesNeeded,@lpServicesReturned,@lpResumeHandle); lpResumeHandle := 0; pStatus := AllocMem(pcbBytesNeeded); try cbBufSize := pcbBytesNeeded; EnumServicesStatus(hSCDB,p_fType,SERVICE_STATE_ALL,pStatus,cbBufSize,@pcbBytesNeeded,@lpServicesReturned,@lpResumeHandle); Sollte sich der Aufruf von Enumservicesstatus von Deinem unterscheiden: Ich hab' mir die Funktionen selber importiert. |
Hi Chris.
Ähem ... kann man dieses Programm, bzw. diesen Teil daraus mal bekommen? :oops: Mir geht´s nämlich um die Variablendeklarationen und die Frage, wie man dann an die einzelnen Services rankommt. Ich muss gestehen, ich kann mit der entsprechenden Zeile aus dem PSDK
Code:
nicht viel anfangen. Daran scheiterte auch die Umsetzung im YAAM. :(
for ( i = 0; i < dwCount; i++ )
{ ess = *(lpDependencies + i); ... Mathias. |
Moin Mathias,
schick mir doch bitte mal 'ne Erinnerungsmail. Dann kann ich mir das vielleicht heute Abend mal anschauen. |
Moin Mathias,
hilft das weiter?
Code:
unit MAIN;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,winsvc; type TForm1 = class(TForm) TreeView1: TTreeView; procedure FormCreate(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; type PENUM_SERVICE_STATUS = ^ENUM_SERVICE_STATUS; ENUM_SERVICE_STATUS = packed record lpServiceName : PChar; lpDisplayName : PChar; ServiceStatus : SERVICE_STATUS; end; type TcsEnumServicesStatus = function( const hSCManager : DWord; // handle to SCM database const dwServiceType : DWord; // service type const dwServiceState : DWord; // service state const lpServices : PENUM_SERVICE_STATUS; // status buffer const cbBufSize : DWord; // size of status buffer const pcbBytesNeeded : PDWORD; // buffer size needed const lpServicesReturned : PDWord; // number of entries returned const lpResumeHandle : PDWord // next entry ) : Boolean; stdcall; TcsEnumDependentServices = function( const hService : DWord; // handle to service const dwServiceState : DWord; // service state const lpServices : PENUM_SERVICE_STATUS; // status buffer const cbBufSize : DWord; // size of status buffer const pcbBytesNeeded : PDWord; // buffer size needed const lpServicesReturned : PDWord // number of entries returned ) : Boolean; stdcall; TcsOpenSCManager = function( const lpMachineName : PChar; const lpDatabaseName : PChar; const dwDesiredAccess : DWord ) : DWord; stdcall; const SERVICE_ACCEPT_STOP = $00000001; SERVICE_ACCEPT_PAUSE_CONTINUE = $00000002; SERVICE_ACCEPT_SHUTDOWN = $00000004; SERVICE_ACCEPT_PARAMCHANGE = $00000008; SERVICE_ACCEPT_NETBINDCHANGE = $00000010; SERVICE_ACCEPT_HARDWAREPROFILECHANGE = $00000020; SERVICE_ACCEPT_POWEREVENT = $00000040; SERVICE_ACCEPT_SESSIONCHANGE = $00000080; var EnumServicesStatus : TcsEnumServicesStatus; EnumDependentServices : TcsEnumDependentServices; OpenSCManager : TcsOpenSCManager; var Form1: TForm1; implementation {$R *.DFM} var hLib : DWORD; procedure TForm1.FormCreate(Sender: TObject); procedure AddDependentServices(const p_tnRoot : TTreeNode;const p_sServiceName : string;const p_hServiceDB : DWORD); var hService : DWORD; pStatus : PENUM_SERVICE_STATUS; pWork : PENUM_SERVICE_STATUS; cbBufSize : DWord; pcbBytesNeeded : DWord; lpServicesReturned : DWord; i : integer; tnWork : TTreeNode; begin hService := OpenService(p_hServiceDB,PChar(p_sServiceName),SERVICE_ENUMERATE_DEPENDENTS); if hService <> 0 then begin try cbBufSize := 0; pStatus := nil; EnumDependentServices(hService,SERVICE_STATE_ALL,pStatus,cbBufSize,@pcbBytesNeeded,@lpServicesReturned); pStatus := AllocMem(pcbBytesNeeded); try cbBufSize := pcbBytesNeeded; EnumDependentServices(hService,SERVICE_STATE_ALL,pStatus,cbBufSize,@pcbBytesNeeded,@lpServicesReturned); pWork := pStatus; for i := 1 to lpServicesReturned do begin tnWork := TreeView1.Items.AddChild(p_tnRoot,pWork.lpServiceName); AddDependentServices(tnWork,pWork.lpServiceName,p_hServiceDB); inc(pWork); end; finally if Assigned(pStatus) then begin FreeMem(pStatus,pcbBytesNeeded); end; end; finally CloseServiceHandle(hService); end; end; end; var hSCDB : DWord; pStatus : PENUM_SERVICE_STATUS; pWork : PENUM_SERVICE_STATUS; cbBufSize : DWord; pcbBytesNeeded : DWord; lpServicesReturned : DWord; lpResumeHandle : DWord; i : integer; tnWork : TTreeNode; begin TreeView1.Items.Clear; hSCDB := OpenSCManager(nil,nil,SC_MANAGER_ENUMERATE_SERVICE or GENERIC_READ); if hSCDB <> 0 then begin try cbBufSize := 0; pStatus := nil; lpResumeHandle := 0; EnumServicesStatus(hSCDB,SERVICE_WIN32,SERVICE_STATE_ALL,pStatus,cbBufSize,@pcbBytesNeeded,@lpServicesReturned,@lpResumeHandle); lpResumeHandle := 0; pStatus := AllocMem(pcbBytesNeeded); try cbBufSize := pcbBytesNeeded; EnumServicesStatus(hSCDB,SERVICE_WIN32,SERVICE_STATE_ALL,pStatus,cbBufSize,@pcbBytesNeeded,@lpServicesReturned,@lpResumeHandle); pWork := pStatus; for i := 1 to lpServicesReturned do begin tnWork := TreeView1.Items.AddChild(nil,pWork.lpServiceName); AddDependentServices(tnWork,pWork.lpServiceName,hSCDB); inc(pWork); end; finally if Assigned(pStatus) then begin FreeMem(pStatus,pcbBytesNeeded); end; end; finally CloseServiceHandle(hSCDB); end; end; end; initialization begin hLib := LoadLibrary('ADVAPI32.DLL'); if hLib <> 0 then begin @EnumServicesStatus := GetProcAddress(hLib,'EnumServicesStatusA'); if @EnumServicesStatus = nil then raise Exception.Create('EnumServicesStatusA'); @EnumDependentServices := GetProcAddress(hLib,'EnumDependentServicesA'); if @EnumDependentServices = nil then raise Exception.Create('EnumDependentServicesA'); @OpenSCManager := GetProcAddress(hLib,'OpenSCManagerA'); if @OpenSCManager = nil then raise Exception.Create('OpenSCManagerA'); end; end; finalization begin if hLib <> 0 then begin FreeLibrary(hLib); end; end; end. |
Ja. Hat a) weitergeholfen, und ist b) schon eingebaut. 8)
Hier noch mal der ![]() Aber Vorsicht beim Deinstallieren! Ich habe außerdem noch ein Popup-Menü ergänzt und ein paar Bugs gefixt. Aber leere Schlüssel werden auch weiterhin nicht gelöscht. |
Bin wieder da!
Hallo!
Lange hat's gedauert, aber die neue Version ist schon bald fertig! Hier der Link: ![]() Seht euch nicht so viel um, ich hab mit Sourceforge leider noch nicht soviel zu tun... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:31 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz