unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, WinSvc, StdCtrls, Buttons;

type
  TForm1 = class(TForm)
    StaticText1: TStaticText;
    BitBtn1: TBitBtn;
    ListBox1: TListBox;
    procedure BitBtn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure EnumServices(const State: DWORD);

var St1:string;

hSCObject, hService: SC_HANDLE;

lpServices, TmpEnum: PEnumServiceStatus;

lpServiceConfig: PQueryServiceConfig;

I, cbBuffSize, pcbBytesNeeded,

lpServicesReturned, lpResumeHandle: DWORD;



begin
with form1 do
begin


try

    Listbox1.Items.Clear;


   // Открываем менеджер сервисов

   hSCObject := OpenSCManager(nil, nil, SC_MANAGER_ENUMERATE_SERVICE);

   if hSCObject <> 0 then

   try

     lpResumeHandle := 0;

     lpServices := nil;

     // Смотрим сколько нужно памяти чтобы получить информацию

     EnumServicesStatus(hSCObject, SERVICE_WIN32, State,

       lpServices^, 0, pcbBytesNeeded, lpServicesReturned, lpResumeHandle);

     if GetLastError = ERROR_MORE_DATA then

     begin

       // Выделяем нужную память

       GetMem(lpServices, pcbBytesNeeded);

       try

         cbBuffSize := pcbBytesNeeded;

         // Получаем требуемую информацию по установленным сервисам

         if EnumServicesStatus(hSCObject, SERVICE_WIN32, State,

           lpServices^, cbBuffSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle) then

         begin

           TmpEnum := lpServices;

           // Бежим в цикле по записям

           for I := 0 to lpServicesReturned - 1 do

           begin

             // Выводим данные на экран


             begin

               // Наименование сервиса

               St1 := TmpEnum^.lpServiceName;

               // Описание сервиса

               St1:=St1+'|'+TmpEnum^.lpDisplayName;

               // Состояние

               case TmpEnum^.ServiceStatus.dwCurrentState of

                 SERVICE_RUNNING: St1:=St1+'|'+'Работает';

                 SERVICE_STOPPED: St1:=St1+'|'+'Остановлен';

               else

                 St1:=St1+'|'+'Неизвестно';

               end;

               // Для дополнительной информаци по сервису получаем описатель сервиса

               hService := OpenService(hSCObject, TmpEnum^.lpServiceName,

                 SERVICE_QUERY_CONFIG);

               if hService <> 0 then

               try

                 // Смотрим сколько нужно памяти

                 QueryServiceConfig(hService, nil, 0, pcbBytesNeeded);

                 if GetLastError = ERROR_INSUFFICIENT_BUFFER then

                 begin

                   cbBuffSize := pcbBytesNeeded;

                   // Берем память

                   GetMem(lpServiceConfig, pcbBytesNeeded);

                   try

                     // Получаем расширенную информацию по сервису

                     if QueryServiceConfig(hService, lpServiceConfig,

                       cbBuffSize, pcbBytesNeeded) then

                     begin

                       // Путь к сервису

                       St1:=St1+'|'+lpServiceConfig^.lpBinaryPathName;

                       // Доступ к рабочему столу

                       if (lpServiceConfig^.dwServiceType and SERVICE_INTERACTIVE_PROCESS) =

                         SERVICE_INTERACTIVE_PROCESS then

                       begin

                         St1:=St1+'|'+'Да';

                         lpServiceConfig^.dwServiceType :=

                           lpServiceConfig^.dwServiceType - SERVICE_INTERACTIVE_PROCESS;

                       end

                       else

                         St1:=St1+'|'+'Нет';

                       // Тип сервиса

                       case lpServiceConfig^.dwServiceType of

                         SERVICE_WIN32_OWN_PROCESS:

                           St1:=St1+'|'+'Одиночный';

                         SERVICE_WIN32_SHARE_PROCESS:

                           St1:=St1+'|'+'Не одиночный';

                       else

                          St1:=St1+'|'+'Неизвестный тип службы';

                       end;

                       // Группа

                       St1:=St1+'|'+lpServiceConfig^.lpLoadOrderGroup;

                       // Тип запуска

                       case lpServiceConfig^.dwStartType of

                         SERVICE_AUTO_START:

                           St1:=St1+'|'+'Автоматический';

                         SERVICE_DEMAND_START:

                           St1:=St1+'|'+'Вручную';

                         SERVICE_DISABLED:

                           St1:=St1+'|'+'Отключен';

                       end;

                     end;

                   // Завершающее освобождение памяти

                   finally

                     FreeMem(lpServiceConfig);

                   end;

                 end;

               finally

                 CloseServiceHandle(hService);

               end;

             end;

             Inc(TmpEnum);
           ListBox1.Items.Add(St1);
           end;

         end;

       finally

         FreeMem(lpServices);

       end;

     end;


   finally

     CloseServiceHandle(hSCObject);

   end;

finally


   StaticText1.Caption := ' Общее количество: ' +

     IntToStr(ListBox1.Items.Count);

end;
end;
end;





procedure TForm1.BitBtn1Click(Sender: TObject);
begin
{if rgServiceState.ItemIndex = 0 then}
   EnumServices(SERVICE_STATE_ALL) ;
end;
end.
