Текущий архив: 2005.10.02;
Скачать: CL | DM;
Вниз
Работа с сервисами в WinXP Найти похожие ветки
← →
highlander © (2005-09-05 18:02) [0]Мне поставили вот такую задачу:
создать сервис для ВинХР, который работает с протоколом РОР3. Сервис запускается автоматически при старте винды. Через заданный промежуток времени сервис опрашивает почтовый ящик на наличие в нем почты. Если почта есть в ящике - то просто показать сообщение, что почта есть. А проблема заключается в том, что после запуска служба сразу останавливается, говоря при этом, что ей нечего делать. Итак, код :
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
Psock, NMpop3, ExtCtrls, inifiles;
type
TService1 = class(TService)
Timer1: TTimer;
NMPOP31: TNMPOP3;
procedure ServiceStart(Sender: TService; var Started: Boolean);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
function GetServiceController: TServiceController; override;
{ Public declarations }
end;
var
Service1: TService1;
implementation
{$R *.DFM}
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);
var
ini:TInifile;
begin
ini:=Tinifile.Create(extractfilepath(paramstr(0))+"service.ini");
NMPOP31.Host:=Ini.ReadString("POP3","host","");
NMPOP31.UserID:=Ini.ReadString("POP3","userID","");
NMPOP31.Password:=Ini.ReadString("POP3","password","");
NMPOP31.Connect;
if NMPOP31.MailCount>0 then
showmessage("You got a new post")
else showmessage("Fuck off! there is no post!");
NMPOP31.Disconnect;
end;
procedure TService1.Timer1Timer(Sender: TObject);
begin
NMPOP31.Connect;
if NMPOP31.MailCount>0 then
showmessage("You got a new post")
else showmessage("Fuck off! there is no post!");
NMPOP31.Disconnect;
end;
end.
← →
highlander © (2005-09-05 18:14) [1]Таймер настроен на 10 минут.
← →
Digitman © (2005-09-05 18:17) [2]а в твоем коде ей действительно нечего делать.
центральная логика сервиса д.б. сосредоточена в обработчике события OnExecute, а ты это событие никак не обрабатываешь
зато почему-то лезешь за почтой в событии OnStart, которое в общем-то предназначено для иных целей - начальная инициализация сервиса при старте .. равно как и OnStop предназначено для деинициализации сервиса перед его остановом
к тому же обработчик OnTimer у тебя работает в осн.трэде процесса сервис-приложения, а поскольку TTimer создает окно, то без взаимодействия сервиса с десктопом окно это получать сообщения не будет, т.е. TTimer работать в такой ситуации не будет.
← →
highlander © (2005-09-05 18:22) [3]огромнейшее спасибо! а не подскажете где можно более подробно почитать о создании сервисов и работе с ними...?
← →
Digitman © (2005-09-05 18:30) [4]навскидку не подскажу.
в принципе для детального изучения достаточно станд.справки Борланда и открытости исх.текстов (winsvc.pas, svcmgr.pas)
← →
highlander © (2005-09-05 19:57) [5]Тогда еще вопрос: если таймер заставить создавать файл, то как правильно это сделать? Так:
procedure TService1.Timer1Timer(Sender: TObject);
var f:textfile;
begin
NMPOP31.Connect;
if NMPOP31.MailCount>0 then
begin
Assignfile(f,"c:\test.txt");
rewrite(f);
writeln(f,time);
end;
NMPOP31.Disconnect;
end;
Или есть варианты получше?
← →
Eraser © (2005-09-05 20:41) [6]highlander © (05.09.05 19:57) [5]
Для работы с файлами лучше использовать TFileStream.
← →
highlander © (2005-09-05 20:59) [7]Даже используя обработчик события OnExecute служба останавливается самостоятельно даже не предупреждая об этом. Приведу новый вариант кода:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
Psock, NMpop3, ExtCtrls, inifiles;
type
TService1 = class(TService)
Timer1: TTimer;
NMPOP31: TNMPOP3;
procedure Timer1Timer(Sender: TObject);
procedure ServiceExecute(Sender: TService);
private
{ Private declarations }
public
function GetServiceController: TServiceController; override;
{ Public declarations }
end;
var
Service1: TService1;
implementation
{$R *.DFM}
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
Service1.Controller(CtrlCode);
end;
function TService1.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure TService1.ServiceExecute(Sender: TService);
var
ini:TInifile;
f:TextFile;
begin
ini:=Tinifile.Create(extractfilepath(paramstr(0))+"service.ini");
NMPOP31.Host:=Ini.ReadString("POP3","host","");
NMPOP31.UserID:=Ini.ReadString("POP3","userID","");
NMPOP31.Password:=Ini.ReadString("POP3","password","");
NMPOP31.Connect;
if NMPOP31.MailCount>0 then
begin
Assignfile(f,"c:\test.txt");
rewrite(f);
writeln(f,time);
end;
NMPOP31.Disconnect;
timer1timer(sender);
end;
procedure TService1.Timer1Timer(Sender: TObject);
var f:textfile;
begin
NMPOP31.Connect;
if NMPOP31.MailCount>0 then
begin
Assignfile(f,"c:\test.txt");
rewrite(f);
writeln(f,time);
end;
NMPOP31.Disconnect;
end;
end.
И файл не создается...
← →
Digitman © (2005-09-06 09:06) [8]останавливается или не стартует вообще ?
← →
Anderson2005 (2005-09-06 10:01) [9]procedure TService1.ServiceStart(Sender: TService;
var Started: Boolean);
begin
Timer.Interval := 3000;
Timer.OnTimer := StartServiceOnTimer;
Timer.Enabled := True;
Started:=True;
end;
procedure TService1.StartServiceOnTimer;
var
ini:TInifile;
f:TextFile;
begin
ini:=Tinifile.Create(extractfilepath(paramstr(0))+"service.ini");
NMPOP31.Host:=Ini.ReadString("POP3","host","");
NMPOP31.UserID:=Ini.ReadString("POP3","userID","");
NMPOP31.Password:=Ini.ReadString("POP3","password","");
NMPOP31.Connect;
if NMPOP31.MailCount>0 then
begin
Assignfile(f,"c:\test.txt");
rewrite(f);
writeln(f,time);
end;
NMPOP31.Disconnect;
end
Попробуй так!
← →
highlander © (2005-09-06 11:03) [10]
> Anderson2005 (06.09.05 10:01) [9] Timer.OnTimer := StartServiceOnTimer;
а разве так можно? И где у сервиса взять TService1.StartServiceOnTimer? Определять самому?
← →
DesWind © (2005-09-06 13:50) [11]highlander © (05.09.05 20:59) [7]
Даже используя обработчик события OnExecute служба останавливается самостоятельно даже не предупреждая об этом. Приведу новый вариант кода:
Пример из Борландовской справки:
procedure TService1.Service1Execute(Sender: TService);
begin
Stream := TMemoryStream.Create;
try
ServerSocket1.Port := 80; // WWW port
ServerSocket1.Active := True;
while not Terminated do begin
ServiceThread.ProcessRequests(True);
end;
ServerSocket1.Active := False;
finally
Stream.Free;
end;
end;
После выполнения кода в OnExecute сервис завершает работу.
← →
Digitman © (2005-09-06 18:45) [12]
> DesWind © (06.09.05 13:50) [11]
не пугай автора.
ничто не мешает организовать в теле OnExecute цикл с нужным условием по выходу из него.
другой вопрос, что в цикле как можно чаще следует вызывать метод ProcessRequests(), иначе сервис будет "глухим" и не будет реагировать (или вовремя реагировать) на команды его останова
Страницы: 1 вся ветка
Текущий архив: 2005.10.02;
Скачать: CL | DM;
Память: 0.5 MB
Время: 0.067 c