Moin F.W.,
hier mal ein Beispiel, wie man die sich die Services die als Starttype "Automatisch" haben in einem Memo anzeigen lassen kann.
Da ich teilweise etwas mit Borlands Deklarationen auf dem Kriegsfuss stehe, habe ich einen Teil der Funktionen/Strukturen selber deklariert. Zusätzlich muss noch die
Unit WinSvc mit eingebunden werden.
Auf eine Kommentierung habe ich vorerst mal verzichtet. Schau es Dir einfach mal in Ruhe an, und versuch' mal nachzuvollziehen was da passiert.
Eines möchte ich allerdings schon vorab erklären:
Funktionen, die eine bestimmte Buffergrösse erfordern kann man mit gezielt zu kleinem Buffer aufrufen, damit sie einem zurückgeben wieviel Platz sie brauchen. Deshalb tauchen Funktionsaufrufe mehrfach auf.
Delphi-Quellcode:
type
PENUM_SERVICE_STATUS = ^ENUM_SERVICE_STATUS;
ENUM_SERVICE_STATUS = packed record
lpServiceName : PCHAR;
lpDisplayName : PCHAR;
ServiceStatus : SERVICE_STATUS;
end;
PQUERY_SERVICE_CONFIG = ^QUERY_SERVICE_CONFIG;
QUERY_SERVICE_CONFIG = packed record
dwServiceType : DWORD;
dwStartType : DWORD;
dwErrorControl : DWORD;
lpBinaryPathName : PCHAR;
lpLoadOrderGroup : PCHAR;
dwTagId : DWORD;
lpDependencies : PCHAR;
lpServiceStartName : PCHAR;
lpDisplayName : PCHAR;
end;
function EnumServicesStatus(
const hSCManager : DWORD;
const dwServiceType : DWORD;
const dwServiceState : DWORD;
const lpServices : PENUM_SERVICE_STATUS;
const cbBufSize : DWORD;
const pcbBytesNeeded : PDWORD;
const lpServicesReturned : PDWORD;
const lpResumeHandle : PDWORD
) : Longbool; stdcall; external 'advapi32.dll' name 'EnumServicesStatusA';
function QueryServiceConfig(
const hService : DWORD;
const lpServiceConfig : PQUERY_SERVICE_CONFIG;
const cbBufSize : DWORD;
const pcbBytesNeeded : PDWORD
) : Longbool; stdcall; external 'advapi32.dll' name 'QueryServiceConfigA';
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var
hSCDB : DWORD;
hService : DWORD;
pStatus : PENUM_SERVICE_STATUS;
pWork : PENUM_SERVICE_STATUS;
pServiceConfig : PQUERY_SERVICE_CONFIG;
cbBufSize : DWORD;
dwSaveBufSize : DWORD;
pcbBytesNeeded : DWORD;
lpServicesReturned : DWORD;
lpResumeHandle : DWORD;
i : integer;
begin
hSCDB := OpenSCManager(nil,nil,SC_MANAGER_ENUMERATE_SERVICE or GENERIC_READ);
if hSCDB = 0 then begin
ShowMessage(SysErrorMessage(GetLastError));
exit;
end;
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;
dwSaveBufSize := cbBufSize;
if not EnumServicesStatus(hSCDB,SERVICE_WIN32,SERVICE_STATE_ALL,pStatus,cbBufSize,@pcbBytesNeeded,@lpServicesReturned,@lpResumeHandle) then begin
ShowMessage(SysErrorMessage(GetLastError));
exit;
end;
pWork := pStatus;
Memo1.Lines.Clear;
for i := 1 to lpServicesReturned do begin
hService := OpenService(hSCDB,pWork.lpServiceName,GENERIC_READ);
if hService <> 0 then begin
pServiceConfig := nil;
cbBufSize := 0;
pcbBytesNeeded := 0;
QueryServiceConfig(hService,pServiceConfig,cbBufSize,@pcbBytesNeeded);
pServiceConfig := AllocMem(pcbBytesNeeded);
try
cbBufSize := pcbBytesNeeded;
if QueryServiceConfig(hService,pServiceConfig,cbBufSize,@pcbBytesNeeded) then begin
if pServiceConfig.dwStartType = SERVICE_AUTO_START then begin
Memo1.Lines.Add(pServiceConfig.lpDisplayName);
end;
end else begin
ShowMessage(SysErrorMessage(GetLastError));
end;
finally
if pServiceConfig <> nil then FreeMem(pServiceConfig,cbBufSize);
end;
end else begin
ShowMessage(SysErrorMessage(GetLastError));
end;
inc(pWork);
end;
finally
if pStatus <> nil then FreeMem(pStatus,dwSaveBufSize);
end;
finally
CloseServiceHandle(hSCDB);
end;
end;