Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Dienste auflisten (https://www.delphipraxis.net/184795-dienste-auflisten.html)

Captnemo 21. Apr 2015 18:05


Dienste auflisten
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich möchte mir alle laufenden Dienste auflisten lassen.

Bedient habe ich mich des Codes von Christian Seehase http://www.delphipraxis.net/21372-re...tallieren.html mit ein paar kleinen, für meinen Zweck nützlichen, Änderungen, die sich aber in keiner Weise auf die Funktion auswirken sollte.

Hier mal meine Unit:
Delphi-Quellcode:
unit uListServicesV;

interface

uses WinSvc, System.Types, windows, System.Classes, System.SysUtils;

type
   // für selbstimportierte Funktion erforderlich
   PENUM_SERVICE_STATUS = ^TEnumServiceStatus;

   // Funktion selber importieren, da die Borland Version nur den ersten zugreifbar macht
   function EnumServicesStatus(
     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; external 'advapi32.dll' name 'EnumServicesStatusA';


procedure GetServiceNames(const Names: TStringList);

implementation

procedure GetServiceNames(const Names: TStringList);
var
   hSCDB : DWORD;
   pStatus : PENUM_SERVICE_STATUS;
   pWork : PENUM_SERVICE_STATUS;
   cbBufSize : DWORD;
   pcbBytesNeeded : DWORD;
   lpServicesReturned : DWORD;
   lpResumeHandle : DWORD;
   iCount : integer;

begin
   Names.Clear;
   hSCDB := OpenSCManager(
     nil, //PChar('\\'+AsComputerName), // Dienste des angegebenen Rechners auslesen
     nil, // Standarddatenbank nehmen
     SC_MANAGER_ENUMERATE_SERVICE // Dienste aufzählen (alle durchgehen)
       or // ausserdem
     GENERIC_READ); // genügt es die Daten nur zu lesen
   if hSCDB <> 0 then begin
     try
       // Erforderlichen Speicherplatz für alle Daten von der Funktion ermitteln lassen
       // ==> gezielt mit 0 Byte Buffer fehlschlagen lassen
       cbBufSize := 0;
       pStatus := nil;
       lpResumeHandle := 0;
       EnumServicesStatus(hSCDB,SERVICE_WIN32,SERVICE_STATE_ALL,pStatus,cbBufSize,@pcbBytesNeeded,@lpServicesReturned,@lpResumeHandle);
       lpResumeHandle := 0;

       // speicher reservieren
       pStatus := AllocMem(pcbBytesNeeded);
       try
         cbBufSize := pcbBytesNeeded;
         EnumServicesStatus(
           hSCDB, // Handle von OpenSCManager
           SERVICE_WIN32, // Nur Dienste, keine Treiber
           SERVICE_STATE_ALL, // Alle installierten Dienste, egal ob sie laufen oder nicht
           pStatus,cbBufSize,@pcbBytesNeeded,@lpServicesReturned,@lpResumeHandle);
         // Adresse merken, damit der Speicher später wieder freigegeben werden kann, ohne den Pointer
         // wieder zurückrechnen zu müssen
         pWork := pStatus;
         // Alle Dienste in Listbox anzeigen (mit Namen und Anzeigenamen)
         for iCount := 1 to lpServicesReturned do begin
           Names.Add(pWork.lpServiceName+'/'+pWork.lpDisplayName);
           inc(pWork);
         end;
       finally
         if Assigned(pStatus) then FreeMem(pStatus,pcbBytesNeeded);
       end;
     finally
       CloseServiceHandle(hSCDB);
     end;
   end;
end;

end.
Entgegen der Annahme, dass sich jetzt in meiner Stringlist die Dienste befinden, erhalte ich lediglich chinesische Schriftzeichen, was sicherlich auf der Tatsache, dass diese Informationen aus falscher Stelle gelesen werden.
Nun habe ich aber zum einen den Code per Copy&Paste (jaja, ich weiß) aus dem Beitrag entnommen habe, denke ich mal das diese soweit eigentlich richtig sein müsste, was wieder durch die Tatsache unterstützt wird, dass er von Christian Seehase stammt.

Nur wo liegt der Fehler? Ich verwende Windows 8. Kann das der Grund sein?

Ich habe auch mal den Code von Michael Puff http://michael-puff.de/Programmierun...Services.shtml ausprobiert, und komme logischerweise auf das gleich, nicht nutzbare Ergebnis.

himitsu 21. Apr 2015 18:20

AW: Dienste auflisten
 
Wetten, daß es von TEnumServiceStatus mehrere Versionen gibt? (Ansi und Unicode ... da du D2009+ nutzt, also Unicode)
Und dennoch rufst du explizit die AnsiVersion der API auf. :stupid:

Und ich befürchte, daß Result=Boolean eventuell falsch ist.

Captnemo 21. Apr 2015 18:24

AW: Dienste auflisten
 
Shit...die Wette würdest du gewinnen ;) Mal schauen ob ich das ohne weitere Hilfe hinkriege.

Captnemo 21. Apr 2015 18:35

AW: Dienste auflisten
 
Danke. Mit EnumServicesStatusW passt's dann wieder.

himitsu 21. Apr 2015 18:47

AW: Dienste auflisten
 
Und LongBool als Result. (siehe mein Nachtrag im letzten Post und siehe MSDN)

Dalai 21. Apr 2015 19:20

AW: Dienste auflisten
 
Hat das einen bestimmten Grund, dass du alle Dienste auflisten lässt (SERVICE_STATE_ALL), wenn du laut eigener Aussage nur die laufenden haben möchtest (SERVICE_ACTIVE)?

MfG Dalai

Captnemo 22. Apr 2015 08:02

AW: Dienste auflisten
 
Zitat:

Zitat von Dalai (Beitrag 1298718)
Hat das einen bestimmten Grund, dass du alle Dienste auflisten lässt (SERVICE_STATE_ALL), wenn du laut eigener Aussage nur die laufenden haben möchtest (SERVICE_ACTIVE)?

Da hab ich mich im ersten Post falsch ausgedrückt. Es müssen alle Dienste aufgelistet werden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:22 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz