Enumerate Services via EnumServicesStatus - Delphi

DarkCoderSc personal avatar
DarkCoderSc

Jean-Pierre LESUEUR

uses
  System.Classes, System.SysUtils, Winapi.Windows, Winapi.WinSvc, Generics.Collections;

// ...

function EnumWindowsServices(var AList : TList<String>) : Cardinal;
begin
  result := 0;
  ///

  if not Assigned(AList) then
    AList := TList<String>.Create()
  else
    AList.CLear();

  var AServiceManager := OpenSCManager(nil, nil, SC_MANAGER_ENUMERATE_SERVICE);
  if AServiceManager = 0 then
    raise EWindowsException.Create('OpenSCManager');
  try
    var AEnumServiceTypes := SERVICE_DRIVER or
                             SERVICE_FILE_SYSTEM_DRIVER or
                             SERVICE_KERNEL_DRIVER or
                             SERVICE_WIN32 or
                             SERVICE_WIN32_OWN_PROCESS or
                             SERVICE_WIN32_SHARE_PROCESS;


    var ARequiredBufferSize : DWORD := 0;
    var AServiceCount : DWORD := 0;
    var AResumeHandle : DWORD := 0;

    if not EnumServicesStatus(
        AServiceManager,
        AEnumServiceTypes,
        SERVICE_STATE_ALL,
        nil,
        0,
        ARequiredBufferSize,
        AServiceCount,
        AResumeHandle
    ) then
      if GetLastError() <> ERROR_MORE_DATA then
        raise EWindowsException.Create('EnumServicesStatus(1)');

    var pServices : PEnumServiceStatus;
    GetMem(pServices, ARequiredBufferSize);
    try
      if not EnumServicesStatus(
          AServiceManager,
          AEnumServiceTypes,
          SERVICE_STATE_ALL,
          pServices,
          ARequiredBufferSize,
          ARequiredBufferSize,
          AServiceCount,
          AResumeHandle
      ) then
        raise EWindowsException.Create('EnumServicesStatus(2)');

      var pService := pServices; // First Row
      for var I := 0 to AServiceCount -1 do begin
        AList.Add(pService^.lpServiceName);

        ///
        Inc(pService);
      end;
    finally
      FreeMem(pServices, ARequiredBufferSize);
    end;
  finally
    CloseServiceHandle(AServiceManager);
  end;

  ///
  result := AList.Count;
end;

// ...

var AList := TList<String>.Create();
try
  EnumWindowsServices(AList);

  for var AServiceName in AList do
    WriteLn(AServiceName);
finally
  FreeAndNil(AList);
end;

Creating and researching code snippets takes time and effort. You’re welcome to share them through your own platforms, but please don’t forget to credit the original author, here: Jean-Pierre LESUEUR.


Created

April 28, 2025

Last Revised

April 28, 2025