Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Пример программы работающей в двух режимах, как сервис и как консольное приложение 
:(
    Опции темы
dvamaster
Дата 28.2.2011, 05:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 559
Регистрация: 30.6.2004
Где: Россия : Курган

Репутация: 3
Всего: 10



Эта программа может работать в двух режимах: как консольное приложение и как сервис.
Функциональная часть удалена, для ее включения необходимо реализовать класс TCore

Ключи:
нет ключей - консольное приложение
-s - сервис
-r - запуск установленного сервиса
-i - установка приложения как сервис (ручной запуск сервиса)
-a - автоматический запуск сервиса (совместно с -i)
-u - удаление сервиса

И так реализация:

test.dpr
Код

program testconsoleservice;

uses
  Windows,
  ParamsUnit in 'ParamsUnit.pas',
  ConsoleUnit in 'ConsoleUnit.pas',
  ServiceUnit in 'ServiceUnit.pas',
  CoreUnit in 'CoreUnit.pas';

begin
  InitParams;
  if GetParamCount = 0 then
    begin
      StartConsole;
      Exit
    end;
  if ParamPresent('-s') then
    begin
      StartingService;
      Exit
    end;
  if ParamPresent('-r') then
    begin
      RunService;
      Exit
    end;
  if ParamPresent('-i') then
    begin
      InstallService(ParamPresent('-a'));
      Exit
    end;
  if ParamPresent('-u') then
    begin
      UninstallService;
      Exit
    end
end.


ParamsUnit.pas

Код

unit ParamsUnit;

interface

uses
  Windows;

procedure InitParams;
function GetParamCount: Integer; stdcall;
function GetParam(AIndex: Integer): PChar; stdcall;
function ParamPresent(AParam: PChar): BOOL; stdcall;

implementation

var
    FParams: array [0..1023] of Char;

procedure InitParams;
var
  i, j: Integer;
  f: Boolean;
begin
  lstrcpy(@FParams, GetCommandLine);
  f := false;
  for i := 0 to 1023 do
    if (FParams[i] <> '-') or f then
      begin
        if FParams[i] = '"' then
          f := not f;
        FParams[i] := #0;
      end else
      Break;
  for i := i to 1023 do
    if FParams[i] <> #0 then
      begin
        if FParams[i] = '-' then
          for j := i - 1 downto 0 do
            if FParams[j] = ' ' then
              FParams[j] := #0 else
              Break;
      end else
      Exit
end;

function GetParamCount: Integer;
var
  i: Integer;
begin
  Result := 0;
  for i := 0 to 1023 do
    if FParams[i] = '-' then
      Result := Result + 1
end;

function GetParam(AIndex: Integer): PChar;
var
  i, ind: Integer;
begin
  Result := nil;
  ind := 0;
  for i := 0 to 1023 do
    if FParams[i] = '-' then
      begin
        if ind = AIndex then
          begin
            Result := @FParams[i];
            Exit
          end;
        ind := ind + 1
      end
end;

function ParamPresent(AParam: PChar): BOOL;
var
  i: Integer;
begin
  Result := false;
  for i := 0 to 1023 do
    if FParams[i] = '-' then
      begin
        Result := lstrcmp(AParam, @FParams[i]) = 0;
        if Result then
          Exit
      end
end;

end.


ConsoleUnit.pas

Код

unit ConsoleUnit;

interface

uses
  Windows;

procedure StartConsole;

implementation

uses
  CoreUnit;

function CtrlHandler(fdwCtrlType: DWORD): BOOL; stdcall;
begin
  Result := true;
  case fdwCtrlType of
    CTRL_C_EVENT,
    CTRL_BREAK_EVENT,
    CTRL_CLOSE_EVENT,
    CTRL_LOGOFF_EVENT,
    CTRL_SHUTDOWN_EVENT: Core.Terminate
  else
    Result := false
  end
end;

procedure StartConsole;
begin

  if not AllocConsole then
    begin
//      LogError
      Exit
    end;
  if not SetConsoleCtrlHandler(@CtrlHandler, true) then
    begin
      FreeConsole;
//      LogError
      Exit
    end;
  Core := TCore.Create;
  if Core.Init then
    Core.Run;
  Core.Free;
  FreeConsole
end;

end.


ServiceUnit.pas

Код

unit ServiceUnit;

interface

uses
  Windows, WinSvc;

procedure StartingService;
procedure RunService;
procedure InstallService(AAuto: Boolean);
procedure UninstallService;

implementation

uses
  CoreUnit;

const
  szServiceName: array [0..18] of Char = 'testconsoleservice';
  szServiceDisplayName: array [0..19] of Char = 'Тест Сервис Консоль';

var
  DispatchTable: array [0..1] of SERVICE_TABLE_ENTRY;
  ServiceStatus: SERVICE_STATUS;
  ServiceStatusHandle: SERVICE_STATUS_HANDLE;

procedure ServiceCtrlHandler(fdwControl: DWORD);
begin
  case fdwControl of
    SERVICE_CONTROL_STOP: begin
      ServiceStatus.dwWin32ExitCode := 0;
      ServiceStatus.dwCurrentState := SERVICE_STOPPED;
      ServiceStatus.dwCheckPoint := 0;
      ServiceStatus.dwWaitHint := 0;
      Core.Terminate;
      if not SetServiceStatus(ServiceStatusHandle, ServiceStatus) then
        begin
//          LogError
          Exit
        end;
    end;
    SERVICE_CONTROL_INTERROGATE: ;
  end
end;

procedure ServiceMain(dwArgc: DWORD; lpszArgv: LPTSTR);
begin
  ServiceStatus.dwServiceType := SERVICE_WIN32;
  ServiceStatus.dwCurrentState := SERVICE_START_PENDING;
  ServiceStatus.dwControlsAccepted := SERVICE_ACCEPT_STOP;
  ServiceStatus.dwWin32ExitCode := 0;
  ServiceStatus.dwServiceSpecificExitCode := 0;
  ServiceStatus.dwCheckPoint := 0;
  ServiceStatus.dwWaitHint := 0;

  ServiceStatusHandle := RegisterServiceCtrlHandler(@szServiceName,
    @ServiceCtrlHandler);

  if ServiceStatusHandle = 0 then
    begin
//      LogError
      Exit
    end;

  Core := TCore.Create;

  if not Core.Init then
    begin
      ServiceStatus.dwCurrentState := SERVICE_STOPPED;
      ServiceStatus.dwCheckPoint := 0;
      ServiceStatus.dwWaitHint := 0;
      ServiceStatus.dwWin32ExitCode := 0;
      ServiceStatus.dwServiceSpecificExitCode := 0;

      SetServiceStatus(ServiceStatusHandle, ServiceStatus);
//      LogError
      Core.Free;
      Exit
  end;

  ServiceStatus.dwCurrentState := SERVICE_RUNNING;
  ServiceStatus.dwCheckPoint := 0;
  ServiceStatus.dwWaitHint := 0;

  if not SetServiceStatus(ServiceStatusHandle, ServiceStatus) then
    begin
//      LogError
      Core.Free;
      Exit
    end;
  Core.Run;
  Core.Free
end;

procedure StartingService;
begin
  DispatchTable[0].lpServiceName := @szServiceName;
  DispatchTable[0].lpServiceProc := @ServiceMain;
  DispatchTable[1].lpServiceName := nil;
  DispatchTable[1].lpServiceProc := nil;
  StartServiceCtrlDispatcher(DispatchTable[0])
end;

procedure RunService;
var
  scm: SC_HANDLE;
  srv: SC_HANDLE;
  p: PChar;
begin
  scm := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if scm = 0 then
    begin
//      LogError
      Exit
    end;
  srv := OpenService(scm, @szServiceName, SERVICE_ALL_ACCESS);
  if srv = 0 then
    begin
//      LogError
      Exit
    end;
  p := nil;
  if not StartService(srv, 0, p) then
    begin
      CloseServiceHandle(srv);
//      LogError
      Exit
    end;
  CloseServiceHandle(srv)
end;

procedure InstallService(AAuto: Boolean);
var
  scm: SC_HANDLE;
  srv: SC_HANDLE;
  st: Cardinal;
  fn, sc: array [0..1023] of Char;
begin
  GetModuleFileName(0, @fn, 1024);
  lstrcpy(sc, '"');
  lstrcat(sc, @fn);
  lstrcat(sc, '" -s');
  scm := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if scm = 0 then
    begin
//      LogError
      Exit
    end;
  st := SERVICE_DEMAND_START;
  if AAuto then
    st := SERVICE_AUTO_START;
  srv := CreateService(scm, @szServiceName, @szServiceDisplayName,
    SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, st, SERVICE_ERROR_NORMAL,
    @sc, nil , nil, nil, nil, nil);
  if srv = 0 then
    begin
//      LogError
      Exit
    end;
  CloseServiceHandle(srv)
end;

procedure UninstallService;
var
  scm: SC_HANDLE;
  srv: SC_HANDLE;
begin
  scm := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if scm = 0 then
    begin
//      LogError
      Exit
    end;
  srv := OpenService(scm, @szServiceName, SERVICE_ALL_ACCESS);
  if srv = 0 then
    begin
//      LogError
      Exit
    end;
  if not DeleteService(srv) then
    begin
      CloseServiceHandle(srv);
//      LogError
      Exit
    end;
  CloseServiceHandle(srv)
end;

end.


CoreUnit.pas

Код

unit CoreUnit;

interface

uses
  Windows;

type
  TCore = class
  private
  public
    constructor Create;
    destructor Destroy; override;
    function Init: BOOL;
    procedure Run;
    procedure Terminate;
  end;

var
  Core: TCore;

implementation

{ TCore }

constructor TCore.Create;
begin
  inherited Create
end;

destructor TCore.Destroy;
begin
  inherited Destroy
end;

function TCore.Init: BOOL;
begin
end;

procedure TCore.Run;
begin
end;

procedure TCore.Terminate;
begin
end;

end.



--------------------
Хорошую информацию трудно добыть. Сделать с ней что-нибудь - еще труднее. /L. Skywalker/

Что же я сделал не так? /Король Лир/

Я делаю это для твоего же блага! /Любой родитель и палач/

PKUNZIP.ZIP /неизвестный/
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0480 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.