Unit winsvc
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';
implementation
{$R *.DFM}
procedure EnumServices(const AsComputerName : string);
var
hSCDB : DWORD;
pStatus : PENUM_SERVICE_STATUS;
pWork : PENUM_SERVICE_STATUS;
cbBufSize : DWORD;
pcbBytesNeeded : DWORD;
lpServicesReturned : DWORD;
lpResumeHandle : DWORD;
iCount : integer;
begin
Form1.ListBox1.Items.Clear;
hSCDB := OpenSCManager(
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
Form1.ListBox1.Items.Add(pWork.lpServiceName+'/'+pWork.lpDisplayName);
inc(pWork);
end;
finally
if Assigned(pStatus) then FreeMem(pStatus,pcbBytesNeeded);
end;
finally
CloseServiceHandle(hSCDB);
end;
end;
end;