Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Создание сервиса используя TService [D7, WinXP]


Dimmu ©   (2003-12-01 14:28:00) 

Здравствуйте. Кто нить может привести код готового сервиса на основе класса TService? Спасибо.


Digitman   (2003-12-02 14:25:00) [1]

в общем случае я как правило поступаю так :



procedure TService1.ProcessSpecialMessage(var Msg: TMessage);
begin
try
... обработка сообщения WM_SOMEMESSAGE, по возможности - максимально короткая по времени
except
end;
end;

procedure TService1.ServiceExecute(Sender: TService);
var
Msg: TMsg;
begin
while not Terminated do
begin
WaitMessage;
if PeekMessage(Msg, 0, WM_SOMEMESSAGE, WM_SOMEMESSAGE, PM_REMOVE) then
ProcessSpecialMessage(PMessage(@Msg.Message)^)
else
ServiceThread.ProcessRequests(False);
end;
end;


в рез-те сервис получает способность быстро реагировать как на контролы, посылаемые системным сервис-менеджером, так и на пользовательские сообщения, посылаемые треду сервиса вызовами PostThreadMessage(WM_SOMEMESSAGE)


Digitman   (2003-12-02 14:19:00) [2]


> Сделал как в хелпе. Если не нужен, то как должен выглядеть
> ServiceExecute?


я речь веду о смысле, заложенном тобой в использовании TSparkyThread, а не о TServiceThread ... он тебе ЗАЧЕМ ?


Digitman   (2003-12-02 14:14:00) [3]


> что делает вот эта строка: ServiceThread.ProcessRequests(True);
>


эта строка отвечает за прием/диспетчеризацию/обработку сообщений-контролов, посылаемых сервис-менеджером потоку сервиса, т.е. Start, Stop, Pause, Continue, Shutdown и пр.пользовательские

без циклического выдова этого метода сервис не будет реагировать на команды сервис-менеджера

если событие сервиса OnExecute() не обрабатывается тобой, то вызов этого метода происходит неявно в коде модуля SvsMgr, в противном случае ответственность за своевременный вызов этого метода возлагается на тебя как на прикл.программиста


procedure TServiceThread.Execute;
var
msg: TMsg;
Started: Boolean;
begin
PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE); { Create message queue }
try
FService.Status := csStartPending;
Started := True;
if Assigned(FService.OnStart) then FService.OnStart(FService, Started);
if not Started then Exit;
try
FService.Status := csRunning;
if Assigned(FService.OnExecute) then
FService.OnExecute(FService)
else
ProcessRequests(True);
ProcessRequests(False);
except
on E: Exception do
FService.LogMessage(Format(SServiceFailed,[SExecute, E.Message]));
end;
except
on E: Exception do
FService.LogMessage(Format(SServiceFailed,[SStart, E.Message]));
end;
end;


Dimmu   (2003-12-02 14:10:00) [4]


>to: Digitman

Сделал как в хелпе. Если не нужен, то как должен выглядеть ServiceExecute? Что типа:
procedure TService1.ServiceExecute(Sender: TService);
begin
while not Terminated do begin
MessageBox(0,"asd","qwe",0);
Sleep(5000);
ServiceThread.ProcessRequests(True);
end;
end;

Или как то по другому?


Digitman   (2003-12-02 13:45:00) [5]

для начала объясни, на кой шут тебе еще один поток, TSparkyThread ? чем это обосновано ?

код сервиса и так исполняется в отдельном потоке


Dimmu   (2003-12-02 12:14:00) [6]


> to zapped


Перенес все как ты сказал, теперь служба долго запускается и в итоге пишет, что служба вовремя не ответила на запрос и по сему не запущена. Так ведь Started:=true я думаю как раз за это и отвечает. Не догоняю от чего так. И еще, если не в лом, скажи как происходит связывание моего потока (TSparkyThread) и ServiceThread. То есть что делает вот эта строка: ServiceThread.ProcessRequests(True); ?


zapped   (2003-12-02 11:50:00) [7]

щас сделал всё по твоему коду :)))
не работает ;)))
обработчики, видать САМ приписывал, а не через Object Inspector :))
перенеси описание их из секции publicтуда, где они по умолчанию пишутся Object Inspector`ом :))
всё заработает... как я до этого додумался, сам не знаю :)))
TService1 = class(TService)
procedure ServiceExecute(Sender: TService);
procedure ServiceStart(Sender: TService; var Started: Boolean);
procedure ServicePause(Sender : TService; var Paused : Boolean);
Procedure ServiceContinue(Sender: TService;
var Continued: Boolean);
procedure ServiceStop(Sender: TService; var Stopped: Boolean);

public
function GetServiceController: TServiceController; override;
end;


Dimmu   (2003-12-02 10:51:00) [8]

Привожу код, чтоб все стало ясно и что вылазиит при старта сервиса.

unit UMain;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs;

type
TSparkyThread = class(TThread)
public
procedure Execute; override;
end;
TService1 = class(TService)
procedure ServiceExecute(Sender: TService);
private
public
function GetServiceController: TServiceController; override;
procedure ServiceStart(Sender: TService; var Started: Boolean);
procedure ServicePause(Sender : TService; var Paused : Boolean);
Procedure ServiceContinue(Sender: TService;
var Continued: Boolean);
procedure ServiceStop(Sender: TService; var Stopped: Boolean);

end;

var
Service1: TService1;
SparkyThread: TSparkyThread;

implementation

{$R *.DFM}

procedure TSparkyThread.Execute;
begin
while not Terminated do
begin
MessageBox(0,"asd","qwe",0);
Sleep(5000);
end;
end;
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
Service1.Controller(CtrlCode);
end;

function TService1.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
SparkyThread:=TSparkyThread.Create(false);
Started := True;
end;

procedure TService1.ServicePause(Sender: TService; var Paused: Boolean);
begin
SparkyThread.Suspend;
Paused := True;
end;

procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
SparkyThread.Terminate;
Stopped:=true;
end;

procedure TService1.ServiceContinue(Sender: TService;
var Continued: Boolean);
begin
SparkyThread.Resume;
Continued:=true;
end;

procedure TService1.ServiceExecute(Sender: TService);
begin
while not Terminated do begin
ServiceThread.ProcessRequests(True);
end;
end;

end.


Вроде все просто, но при запуске появляется след. ошибка:

Exception EReadError in module (не важно) at (тут адрес)
Error reading Service1.OnPause: Invalid property value.

Что в OnPause не так не могу догнать.


zapped   (2003-12-02 02:28:00) [9]

2Dimmu (01.12.03 15:00) [2]
присоединяюсь к Digitman: ЧТО не получилось?


Digitman   (2003-12-01 15:24:00) [10]


> что то не получилось


ЧТО не получилось ?

нормальный старт - возврат Started = True в обработчике OnStart()
нормальный останов - возврат Stopped = True в обработчике OnStop()

куда уж проще ..


Dimmu   (2003-12-01 15:00:00) [11]

Нет, что он делает мне не важно, пускай в том месте будет что то то типа
repeat
// код который крутится
until Terminated;
Самое важное реакции на всякие остановки и т.п. Я пытался запустить пример из хелпа, но что то не получилось.


Digitman   (2003-12-01 14:57:00) [12]


> код готового сервиса


который делает ЧТО ????


Наверх

Титульная страница Поиск, карта сайта Написать письмо