Tuesday, 1 September 2009

Obtener la lista de servicios de nuestro equipo

Si queremos obtener la lista de los servicios que tenemos en nuestro equipo, simplemente hay que recurrir a la API de windows y solicitarla. Mediante Delphi, podemos recuperar la lista fácilmente utilizando la unit WinSvc. Para acceder a la lista de nuestros servicios, podemos ir directamente desde nuestro panel de control. Luego nos dirigimos a Herramientas administrativas y luego a Servicios. En éste formulario encontraréis la lista de servicios que se están ejecutando en la máquina. Mediante éste, podremos visualizar las propiedades de éstos servicios así como iniciarlos o pararlos a nuestro gusto. Pues bien, aquí os dejo una pequeña aplicación que permite visualizar ésta lista (simple) mediante delphi. La aplicación es muy sencilla y os dejo también el código fuente.

Podéis descargar la aplicación : Thundax List of Services, y comprobar la lista que devuelve. El código fuente original lo podéis encontrar en Delphi Source code, de la mano de Alexander Savchev.


El código fuente:

unit Services;

interface

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

type
    TMyApp = class(TForm)
        Button1: TButton;
        ListView1: TListView;
        procedure Button1Click(Sender: TObject);
        procedure ListView1CustomDrawItem(Sender: TCustomListView; Item: TListItem;
            State: TCustomDrawState; var DefaultDraw: Boolean);
    private
        function ServiceGetList(sMachine: string; dwServiceType, dwServiceState: DWord; slServicesList: TListView): boolean;
        { Private declarations }
    public
        { Public declarations }
    end;

const
    cnMaxServices = 4096;

type
    TSvcA = array[0..cnMaxServices]
        of TEnumServiceStatus;
    PSvcA = ^TSvcA;

const
    SERVICE_KERNEL_DRIVER = $00000001;
    SERVICE_FILE_SYSTEM_DRIVER = $00000002;
    SERVICE_ADAPTER = $00000004;
    SERVICE_RECOGNIZER_DRIVER = $00000008;
    SERVICE_DRIVER = (SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER or SERVICE_RECOGNIZER_DRIVER);
    SERVICE_WIN32_OWN_PROCESS = $00000010;
    SERVICE_WIN32_SHARE_PROCESS = $00000020;
    SERVICE_WIN32 = (SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS);
    SERVICE_INTERACTIVE_PROCESS = $00000100;
    SERVICE_TYPE_ALL = (SERVICE_WIN32 or SERVICE_ADAPTER or SERVICE_DRIVER or SERVICE_INTERACTIVE_PROCESS);

implementation

{$R *.dfm}

procedure TMyApp.Button1Click(Sender: TObject);
begin
    ServiceGetList('', SERVICE_WIN32, SERVICE_STATE_ALL, ListView1);
end;

procedure TMyApp.ListView1CustomDrawItem(Sender: TCustomListView;
    Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
    if item.SubItems[1] = 'SERVICE_RUNNING' then
        ListView1.Canvas.Font.Color := clLime
else if item.SubItems[1] = 'SERVICE_STOPPED' then
        ListView1.Canvas.Font.Color := clRed
else
        ListView1.Canvas.Font.Color := clwhite;
end;

function TMyApp.ServiceGetList(sMachine: string; dwServiceType, dwServiceState: DWord; slServicesList: TListView): boolean;
var
    j: integer;
    schm: SC_Handle;
    nBytesNeeded, nServices, nResumeHandle: DWord;
    ssa: PSvcA;
    item: TListItem;
    s: string;
begin
    slServicesList.Clear;
    Result := false;
    schm := OpenSCManager(PChar(sMachine), nil, SC_MANAGER_ALL_ACCESS);
    if (schm > 0) then
    begin
        nResumeHandle := 0;
        New(ssa);
        EnumServicesStatus(schm, dwServiceType, dwServiceState, ssa^[0], SizeOf(ssa^), nBytesNeeded, nServices, nResumeHandle);
        for j := 0 to nServices - 1 do
        begin
            item := slServicesList.items.Add;
            item.Caption := StrPas(ssa^[j].lpDisplayName);
            item.SubItems.Add(StrPas(ssa^[j].lpServiceName));
            case ssa^[j].ServiceStatus.dwCurrentState of
                SERVICE_STOPPED: s := 'SERVICE_STOPPED';
                SERVICE_START_PENDING: s := 'SERVICE_START_PENDING';
                SERVICE_STOP_PENDING: s := 'SERVICE_STOP_PENDING';
                SERVICE_RUNNING: s := 'SERVICE_RUNNING';
                SERVICE_CONTINUE_PENDING: s := 'SERVICE_CONTINUE_PENDING';
                SERVICE_PAUSE_PENDING: s := 'SERVICE_PAUSE_PENDING';
                SERVICE_PAUSED: s := 'SERVICE_PAUSED';
            end;
            item.SubItems.Add(s);
        end;
        Result := true;
        Dispose(ssa);
        CloseServiceHandle(schm);
    end;
end;

end.


  • Enlaces de interés:
Stopping a service windows (API).
Listview Examples.

0 comments:

Post a Comment