Страница 1 из 1

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

СообщениеДобавлено: 01.10.2009 10:30:22
PapaNT
Нужно получить список виндусовых служб для того чтобы потом выделить те, которые запускаются от имени конкретного пользователя.
win API функции нашел, но что-то не смог разобраться с тем, как получить этот список :( пусть даже без фильтрации по пользователям... :roll:

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

СообщениеДобавлено: 01.10.2009 12:16:11
Mr.Smart
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;

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

СообщениеДобавлено: 01.10.2009 13:31:05
PapaNT
К примеру добавил
Код: Выделить всё
uses windows

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

Огромное спасибо!

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

СообщениеДобавлено: 02.02.2010 18:55:55
PapaNT
пошло, но, увы, не все.
на 2003-м серваке работает все, а на 200м только получение статуса служб. А так хочется еще ими и управлять!!! Или хотя бы запускать/останавливать... :roll:

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

СообщениеДобавлено: 02.02.2010 21:42:55
Mr.Smart
В 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;

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

СообщениеДобавлено: 04.02.2010 19:11:04
PapaNT
а что такое?
Код: Выделить всё
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.

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

СообщениеДобавлено: 05.02.2010 13:11:44
Mr.Smart
PapaNT писал(а):а что такое?
Код: Выделить всё
i+=1;

Это нововведение FPC в стиле Си :wink:
Ниже приведённые строки эквивалентны:
Код: Выделить всё
i+=1;
i++;
i:=i+1;
inc(i);

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

СообщениеДобавлено: 05.02.2010 15:20:05
PapaNT
спасибо! Почти догадался :)

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

СообщениеДобавлено: 04.03.2014 17:16:06
mirk
Какими функциями правильнее пользоваться:
EnumServicesStatus (из windows) или EnumServicesStatusW (из jwawinsvc)?

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

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

Но вот как получить текстовое описание службы?

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

СообщениеДобавлено: 12.03.2014 18:22:19
ev
winapi
QueryServiceConfig2 + SERVICE_CONFIG_DESCRIPTION

реестр
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\_name_service_\Description

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

СообщениеДобавлено: 13.03.2014 11:31:46
mirk
ev
Спасибо, то что надо.