Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.02.06;
Скачать: CL | DM;

Вниз

Создание сервиса используя TService   Найти похожие ветки 

 
Dimmu   (2003-12-01 14:28) [0]

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


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


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


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


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

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


 
Digitman ©   (2003-12-01 15:24) [3]


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


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

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

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


 
zapped ©   (2003-12-02 02:28) [4]

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


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

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

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 11:50) [6]

щас сделал всё по твоему коду :)))
не работает ;)))
обработчики, видать САМ приписывал, а не через 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 12:14) [7]


> to zapped


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


 
Digitman ©   (2003-12-02 13:45) [8]

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

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


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


>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 14:14) [10]


> что делает вот эта строка: 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;


 
Digitman ©   (2003-12-02 14:19) [11]


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


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


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

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



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)



Страницы: 1 вся ветка

Текущий архив: 2004.02.06;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.018 c
3-16069
Val
2004-01-12 11:53
2004.02.06
ptOraBlob как параметр TStoredProc


14-16742
Piter
2004-01-15 19:00
2004.02.06
Насчет NtQuerySystemInformation и йCreateToolhelp32Snapshot


14-16724
Lony
2004-01-16 13:11
2004.02.06
Файлы вместо ADO


4-16817
d_oleg
2003-11-28 12:23
2004.02.06
Get Application Title


14-16641
vidiv
2004-01-11 14:57
2004.02.06
DNS Server