Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Перечисление служб

01.01.2007
////////////////////////////////////////////////////////////////////////////////
//
//  ****************************************************************************
//  * Project   : Project1
//  * Unit Name : Unit1
//  * Purpose   : Демо получения информации по сервисам
//  * Author    : Александр (Rouse_) Багель
//  * Version   : 1.00
//  ****************************************************************************
//
 
unit Unit1
;
 
interface
 
uses
 
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 
Dialogs, ComCtrls, StdCtrls, ExtCtrls, WinSvc;
 
type
 
TfrmMain = class(TForm)
    lvReport
: TListView;
    rgServiceState
: TRadioGroup;
    sbCount
: TStatusBar;
    OpenDialog1
: TOpenDialog;
    procedure
FormCreate(Sender: TObject);
    procedure rgServiceStateClick
(Sender: TObject);
 
private
    procedure
EnumServices(const State: DWORD);
 
end;
 
var
  frmMain
: TfrmMain;
 
implementation
 
{$R *.dfm}
 
procedure
TfrmMain.EnumServices(const State: DWORD);
var
  hSCObject
, hService: SC_HANDLE;
  lpServices
, TmpEnum: PEnumServiceStatus;
  lpServiceConfig
: PQueryServiceConfig;
  I
, cbBuffSize, pcbBytesNeeded,
  lpServicesReturned
, lpResumeHandle: DWORD;
begin
  lvReport
.Items.BeginUpdate;
 
try
    lvReport
.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
             
// Выводим данные на экран
             
with lvReport.Items.Add do
             
begin
               
// Наименование сервиса
               
Caption := TmpEnum^.lpServiceName;
               
// Описание сервиса
               
SubItems.Add(TmpEnum^.lpDisplayName);
               
// Состояние
               
case TmpEnum^.ServiceStatus.dwCurrentState of
                  SERVICE_RUNNING
: SubItems.Add('Работает');
                  SERVICE_STOPPED
: SubItems.Add('Остановлен');
               
else
                 
SubItems.Add('Неизвестно');
               
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
                       
// Путь к сервису
                       
SubItems.Add(lpServiceConfig^.lpBinaryPathName);
                       
// Доступ к рабочему столу
                       
if (lpServiceConfig^.dwServiceType and SERVICE_INTERACTIVE_PROCESS) =
                          SERVICE_INTERACTIVE_PROCESS
then
                       
begin
                         
SubItems.Add('Да');
                          lpServiceConfig
^.dwServiceType :=
                            lpServiceConfig
^.dwServiceType - SERVICE_INTERACTIVE_PROCESS;
                       
end
                       
else
                         
SubItems.Add('Нет');
                       
// Тип сервиса
                       
case lpServiceConfig^.dwServiceType of
                          SERVICE_WIN32_OWN_PROCESS
:
                           
SubItems.Add('Одиночный');
                          SERVICE_WIN32_SHARE_PROCESS
:
                           
SubItems.Add('Не одиночный');
                       
else
                           
SubItems.Add('Неизвестный тип службы');
                       
end;
                       
// Группа
                       
SubItems.Add(lpServiceConfig^.lpLoadOrderGroup);
                       
// Тип запуска
                       
case lpServiceConfig^.dwStartType of
                          SERVICE_AUTO_START
:
                           
SubItems.Add('Автоматический');
                          SERVICE_DEMAND_START
:
                           
SubItems.Add('Вручную');
                          SERVICE_DISABLED
:
                           
SubItems.Add('Отключен');
                       
end;
                     
end;
                   
// Завершающее освобождение памяти
                   
finally
                     
FreeMem(lpServiceConfig);
                   
end;
                 
end;
               
finally
                 
CloseServiceHandle(hService);
               
end;
             
end;
             
Inc(TmpEnum);
           
end;
         
end;
       
finally
         
FreeMem(lpServices);
       
end;
     
end;
   
finally
     
CloseServiceHandle(hSCObject);
   
end;
 
finally
    lvReport
.Items.EndUpdate;
    sbCount
.Panels.Items[0].Text := ' Общее количество: ' +
     
IntToStr(lvReport.Items.Count);
 
end;
end;
 
procedure
TfrmMain.FormCreate(Sender: TObject);
begin
  rgServiceState
.OnClick(nil);
end;
 
procedure
TfrmMain.rgServiceStateClick(Sender: TObject);
begin
 
// В зависимости от выбранного RadioItem перечисляем -
 
// все сервисы, только активные или неактивные
 
if rgServiceState.ItemIndex = 0 then
   
EnumServices(SERVICE_STATE_ALL)
 
else
   
EnumServices(rgServiceState.ItemIndex);
end;
 
end.

Взято из https://forum.sources.ru

Автор: Rouse_