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.