1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
uses Winapi.WinSvc;
Procedure Refresh_Liste_Services(AHandle_SCM : SC_Handle; List: TStrings);
var
lpServices, lpServiceItem: PEnumServiceStatus; // avec PEnumServiceStatus = ^TEnumServiceStatus
cbBufSize: DWORD;
pcbBytesNeeded: DWORD;
lpResumeHandle: DWORD;
lpServicesReturned: DWORD;
Res: Boolean;
I: Integer;
begin
// Premier appel pour déterminer la taille: To determine the required size, specify NULL for this parameter and 0 for the cbBufSize parameter
cbBufSize := 0;
lpServices := nil;
lpResumeHandle := 0; // A pointer to a variable that, on input, specifies the starting point of enumeration. You must set this value to zero the first time this function is called.
Res := EnumServicesStatus(
AHandle_SCM,
SERVICE_WIN32,
SERVICE_STATE_ALL,
lpServices^,
cbBufSize,
pcbBytesNeeded,
lpServicesReturned,
lpResumeHandle);
if not Res then
if GetLastError <> ERROR_MORE_DATA then
RaiseLastOSError();
cbBufSize := pcbBytesNeeded; // la fameuse Astuce du double appel !
GetMem(lpServices, cbBufSize) ;
try
Res := EnumServicesStatus(
AHandle_SCM,
SERVICE_WIN32,
SERVICE_STATE_ALL,
lpServices^,
cbBufSize,
pcbBytesNeeded,
lpServicesReturned,
lpResumeHandle);
if not Res then
RaiseLastOSError();
lpServiceItem := lpServices; // Second astuce pour se passer de la syntaxe tableau
for i := 1 to lpServicesReturned do
begin
List.Add(lpServiceItem.lpDisplayName); // lpServices. ou lpServices^. Delphi est sympa, il sait faire un déréférencement implicite
Inc(lpServiceItem);
end;
finally
FreeMem(lpServices);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
SvcMgr: SC_HANDLE;
begin
// Ajout de la description dans services.msc
SvcMgr := OpenSCManager(nil, nil, SC_MANAGER_ENUMERATE_SERVICE);
try
Refresh_Liste_Services(SvcMgr, Memo1.Lines);
finally
CloseServiceHandle(SvcMgr);
end;
end; |
Partager