Получение списка служб в Windows

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Получение списка служб в Windows

Сообщение PapaNT » 01.10.2009 10:30:22

Нужно получить список виндусовых служб для того чтобы потом выделить те, которые запускаются от имени конкретного пользователя.
win API функции нашел, но что-то не смог разобраться с тем, как получить этот список :( пусть даже без фильтрации по пользователям... :roll:
PapaNT
постоялец
 
Сообщения: 167
Зарегистрирован: 11.09.2009 12:06:46
Откуда: Москва

Re: Получение списка служб в Windows

Сообщение Mr.Smart » 01.10.2009 12:16:11

PapaNT
Примерно вот так:
Код: Выделить всё
const
BuffSize = SizeOf(ENUM_SERVICE_STATUS)*4096;

var
Status: PENUMSERVICESTATUS;
Man: SC_HANDLE;
j: integer;
N: DWord = 0;
R: DWord = 0;
H: DWord = 0;
begin
  Man:=OpenSCManager(nil,nil,SC_MANAGER_ENUMERATE_SERVICE);

  if Man<>0 then
   begin
    Status:=GetMem(BuffSize);
    if EnumServicesStatus(Man,SERVICE_WIN32,SERVICE_ACTIVE,Status,BuffSize,
       @N,@R,@H) then
     begin
      for j:=0 to R-1 do
       ListBox1.Items.Add(Status[j].lpServiceName);
     end;
    Freemem(Status);
    CloseServiceHandle(Man);
   end;
end;
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: Получение списка служб в Windows

Сообщение PapaNT » 01.10.2009 13:31:05

К примеру добавил
Код: Выделить всё
uses windows

и все заработало!

Огромное спасибо!
PapaNT
постоялец
 
Сообщения: 167
Зарегистрирован: 11.09.2009 12:06:46
Откуда: Москва

Re: Получение списка служб в Windows

Сообщение PapaNT » 02.02.2010 18:55:55

пошло, но, увы, не все.
на 2003-м серваке работает все, а на 200м только получение статуса служб. А так хочется еще ими и управлять!!! Или хотя бы запускать/останавливать... :roll:
PapaNT
постоялец
 
Сообщения: 167
Зарегистрирован: 11.09.2009 12:06:46
Откуда: Москва

Re: Получение списка служб в Windows

Сообщение Mr.Smart » 02.02.2010 21:42:55

В 2000-ном работает. Лично проверял и использовал в ПО крутящемся именно под этой ос :wink:
Код: Выделить всё
function ServiceStart(const ServiceName: String): Boolean;
var
h_manager,h_svc: SC_Handle;
svc_status: TServiceStatus;
Temp: PChar;
dwCheckPoint: DWord;
i: Integer;
begin
  svc_status.dwCurrentState := 1;
  h_manager := OpenSCManager(nil, nil, SC_MANAGER_CONNECT);
  if h_manager > 0 then
  begin
    h_svc := OpenService(h_manager, PChar(ServiceName),
    SERVICE_START or SERVICE_QUERY_STATUS);
    if h_svc > 0 then
    begin
      temp := nil;
      i:=0;
      if (StartService(h_svc,0,temp)) then
        if (QueryServiceStatus(h_svc,svc_status)) then
        begin
          while (SERVICE_RUNNING <> svc_status.dwCurrentState) and (i<1000) do
          begin
            i+=1;
            dwCheckPoint := svc_status.dwCheckPoint;
            Sleep(svc_status.dwWaitHint);
            if (not QueryServiceStatus(h_svc,svc_status)) then
              break;
            if (svc_status.dwCheckPoint < dwCheckPoint) then
            begin
              // QueryServiceStatus не увеличивает dwCheckPoint
              break;
            end;
          end;
        end;
      CloseServiceHandle(h_svc);
    end;
    CloseServiceHandle(h_manager);
  end;
  Result := SERVICE_RUNNING = svc_status.dwCurrentState;
end;

function ServiceStop(const ServiceName: String): Boolean;
var
h_manager, h_svc: SC_Handle;
svc_status: TServiceStatus;
dwCheckPoint: DWord;
i: Integer;
begin
  h_manager:=OpenSCManager(nil,nil, SC_MANAGER_CONNECT);
  if h_manager > 0 then
  begin
    h_svc := OpenService(h_manager,PChar(ServiceName),
    SERVICE_STOP or SERVICE_QUERY_STATUS);
    if h_svc > 0 then
    begin
      if(ControlService(h_svc,SERVICE_CONTROL_STOP, svc_status))then
      begin
        if(QueryServiceStatus(h_svc,svc_status))then
        begin
          i:=0;
          while(SERVICE_STOPPED <> svc_status.dwCurrentState) and (i<1000) do
          begin
            i+=1;
            dwCheckPoint := svc_status.dwCheckPoint;
            Sleep(svc_status.dwWaitHint);
            if(not QueryServiceStatus(h_svc,svc_status))then
            begin
              // couldn't check status
              break;
            end;
            if(svc_status.dwCheckPoint < dwCheckPoint)then
              break;
          end;
        end;
      end;
      CloseServiceHandle(h_svc);
    end;
    CloseServiceHandle(h_manager);
  end;
  Result := SERVICE_STOPPED = svc_status.dwCurrentState;
end;
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: Получение списка служб в Windows

Сообщение PapaNT » 04.02.2010 19:11:04

а что такое?
Код: Выделить всё
i+=1;


Добавлено спустя 37 минут 10 секунд:
рабочий код под fp2.2.4. Под текущую версию пока не пересобирал - проблемы с другими моими модулями (для которых написан этот).

Код: Выделить всё
unit my_system;

Interface

Uses Windows,My_Str,SysUtils,jwaWinNT,jwaWinSvc;
Const
  SC_Stopped       = 1; { статусы сервисов }
  SC_Start_Pending = 2;
  SC_Stop_Pending  = 3;
  SC_Running       = 4;
  SC_Paused        = 7;

  SC_Stopped_Str       = 'остановлен';
  SC_Start_Pending_Str = 'останвливается';
  SC_Stop_Pending_Str  = 'запускается';
  SC_Running_Str       = 'работает';
  SC_Paused_Str        = 'приостановлен';

procedure ExecuteControlService(ServiceName: AnsiString; ServiceControlCode : DWORD);
function  ServiceStop(aMachine,aServiceName : AnsiString ) : boolean;
function  ServiceStart(aMachine, aServiceName : AnsiString ) : boolean;
function  ServiceGetStatus(sMachine, sService: AnsiString ): DWord;
function  ServiceSetMode(sMachine, sService: AnsiString; Mode : Word ): Boolean;
Function  ServiceStateStr(State : word) : string;

Implementation

procedure ExecuteControlService(ServiceName: AnsiString; ServiceControlCode : DWORD);
var
SCManagerHandle, SCHandle  : THandle;
ServiceStatus : TServiceStatus;
begin
// 1. подключение к менеджеру сервисов
SCManagerHandle := OpenSCManager(nil, nil, GENERIC_READ);
SCHandle := OpenService(SCManagerHandle, PChar(ServiceName), SERVICE_ALL_ACCESS);
ControlService(SCHandle, ServiceControlCode, ServiceStatus);
CloseServiceHandle(SCHandle);
CloseServiceHandle(SCManagerHandle);
end;

function ServiceStop(aMachine,aServiceName : AnsiString ) : boolean;
// aMachine это UNC путь, либо локальный компьютер если пусто
var
  h_manager,h_svc   : SC_Handle;
  svc_status     : TServiceStatus;
  dwCheckPoint : DWord;
begin
  h_manager:=OpenSCManager(PChar(aMachine),nil,
                           SC_MANAGER_CONNECT);
  if h_manager > 0 then
  begin
    h_svc := OpenService(h_manager,PChar(aServiceName),
                         SERVICE_STOP or SERVICE_QUERY_STATUS);

    if h_svc > 0 then
    begin
      if(ControlService(h_svc,SERVICE_CONTROL_STOP,
                        svc_status))then
      begin
        if(QueryServiceStatus(h_svc,svc_status))then
        begin
          while(SERVICE_STOPPED <> svc_status.dwCurrentState)do
          begin
            dwCheckPoint := svc_status.dwCheckPoint;
            Sleep(svc_status.dwWaitHint);

            if(not QueryServiceStatus(h_svc,svc_status))then
            begin
              // couldn't check status
              break;
            end;

            if(svc_status.dwCheckPoint < dwCheckPoint)then
              break;

          end;
        end;
      end;
      CloseServiceHandle(h_svc);
    end;
    CloseServiceHandle(h_manager);
  end;

  ServiceStop := SERVICE_STOPPED = svc_status.dwCurrentState;
end;

function ServiceStart(aMachine, aServiceName : AnsiString ) : boolean;
// aMachine это UNC путь, либо локальный компьютер если пусто
var
  h_manager,h_svc: SC_Handle;
  svc_status: TServiceStatus;
  Temp: PChar;
  dwCheckPoint: DWord;
begin
  svc_status.dwCurrentState := 1;
  h_manager := OpenSCManager(PChar(aMachine), Nil,
                             SC_MANAGER_CONNECT);
  if h_manager > 0 then
  begin
    h_svc := OpenService(h_manager, PChar(aServiceName),
                         SERVICE_START or SERVICE_QUERY_STATUS);
    if h_svc > 0 then
    begin
      temp := nil;
      if (StartService(h_svc,0,temp)) then
        if (QueryServiceStatus(h_svc,svc_status)) then
        begin
          while (SERVICE_RUNNING <> svc_status.dwCurrentState) do
          begin
            dwCheckPoint := svc_status.dwCheckPoint;

            Sleep(svc_status.dwWaitHint);

            if (not QueryServiceStatus(h_svc,svc_status)) then
              break;

            if (svc_status.dwCheckPoint < dwCheckPoint) then
            begin
              // QueryServiceStatus не увеличивает dwCheckPoint
              break;
            end;
          end;
        end;
      CloseServiceHandle(h_svc);
    end;
    CloseServiceHandle(h_manager);
  end;
  ServiceStart := SERVICE_RUNNING = svc_status.dwCurrentState;
end;

function ServiceGetStatus(sMachine, sService: AnsiString ): DWord;
var
  h_manager,h_service,h_svc: SC_Handle;
  service_status     : TServiceStatus;
  hStat : DWord;
begin
  hStat := 1;
  h_manager := OpenSCManager(PChar(sMachine) ,Nil,
                             SC_MANAGER_CONNECT);

  if h_manager > 0 then
  begin
    h_svc := OpenService(h_manager,PChar(sService),
                      SERVICE_QUERY_STATUS);

    if h_svc > 0 then
    begin
      if(QueryServiceStatus(h_svc, service_status)) then
        hStat := service_status.dwCurrentState;

      CloseServiceHandle(h_svc);
    end;
    CloseServiceHandle(h_manager);
  end;

  ServiceGetStatus := hStat;
end;


function ServiceSetMode(sMachine, sService: AnsiString; Mode : Word ): Boolean;
// Тип запуска сервиса: SERVICE_DEMAND_START
//                      SERVICE_AUTO_START
var
  h_manager,h_service,h_svc: SC_Handle;
  service_status     : TServiceStatus;
//  hStat : DWord;
  SvcLock : SC_Lock;
begin
//  hStat := 1;
  ServiceSetMode := False;
  h_manager := OpenSCManager(PChar(sMachine) ,Nil,
                             SC_MANAGER_All_Access);

  if h_manager > 0 then
  begin
    // Блокируем базу сервисов.
    SvcLock := LockServiceDatabase(h_manager);
    if SvcLock = Nil then
      exit; // Ошибка блокирования сервисов
    h_svc := OpenService(h_manager,PChar(sService),
                      SERVICE_All_Access);

    // Проверим, что удалось обратиться к сервису.
    if h_svc > 0 Then
      begin
        if not ChangeServiceConfig(h_svc,SERVICE_NO_CHANGE,
               Mode, // Тип запуска сервиса: SERVICE_DEMAND_START
                     //                      SERVICE_AUTO_START
               SERVICE_NO_CHANGE,Nil,Nil,Nil,Nil,Nil,Nil,Nil)
                                                              Then
                                                                // Ошибка смены статуса сервиса.
                                                               exit;


      end;
    UnlockServiceDatabase(SvcLock);
    CloseServiceHandle(h_svc);
    CloseServiceHandle(h_manager);

  end
                   else
                     exit; //Выход по ошибке обращения к сервисам.


  ServiceSetMode := True;
end;

Function ServiceStateStr(State : word) : string;
begin
  case State of
    SC_Stopped       : ServiceStateStr := 'Stopped'; { статусы сервисов }
    SC_Start_Pending : ServiceStateStr := 'Start Pending';
    SC_Stop_Pending  : ServiceStateStr := 'Stop Pending';
    SC_Running       : ServiceStateStr := 'Running';
    SC_Paused        : ServiceStateStr := 'Paused';
    1722             : ServiceStateStr := 'The RPC server is unavailable';
    else
      ServiceStateStr := 'Статус: ' + IntToStr(State)
  end { case }
end;


Begin
End.
PapaNT
постоялец
 
Сообщения: 167
Зарегистрирован: 11.09.2009 12:06:46
Откуда: Москва

Re: Получение списка служб в Windows

Сообщение Mr.Smart » 05.02.2010 13:11:44

PapaNT писал(а):а что такое?
Код: Выделить всё
i+=1;

Это нововведение FPC в стиле Си :wink:
Ниже приведённые строки эквивалентны:
Код: Выделить всё
i+=1;
i++;
i:=i+1;
inc(i);
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: Получение списка служб в Windows

Сообщение PapaNT » 05.02.2010 15:20:05

спасибо! Почти догадался :)
PapaNT
постоялец
 
Сообщения: 167
Зарегистрирован: 11.09.2009 12:06:46
Откуда: Москва

Re: Получение списка служб в Windows

Сообщение mirk » 04.03.2014 17:16:06

Какими функциями правильнее пользоваться:
EnumServicesStatus (из windows) или EnumServicesStatusW (из jwawinsvc)?
mirk
постоялец
 
Сообщения: 317
Зарегистрирован: 24.09.2007 10:03:39

Re: Получение списка служб в Windows

Сообщение mirk » 11.03.2014 14:07:01

Научился доставать список служб и их параметры:
- текущий статус
- название
- выводимое название
- выполняемый файл
- тип запуска

Но вот как получить текстовое описание службы?
mirk
постоялец
 
Сообщения: 317
Зарегистрирован: 24.09.2007 10:03:39

Re: Получение списка служб в Windows

Сообщение ev » 12.03.2014 18:22:19

winapi
QueryServiceConfig2 + SERVICE_CONFIG_DESCRIPTION

реестр
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\_name_service_\Description
ev
долгожитель
 
Сообщения: 1772
Зарегистрирован: 27.04.2005 23:19:06
Откуда: Москва

Re: Получение списка служб в Windows

Сообщение mirk » 13.03.2014 11:31:46

ev
Спасибо, то что надо.
mirk
постоялец
 
Сообщения: 317
Зарегистрирован: 24.09.2007 10:03:39


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 24

Рейтинг@Mail.ru
cron