Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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
14-1126683521
Ega23
2005-09-14 11:38
2005.10.02
Есть спецы по Sybase PoewrDesigner?


14-1126696545
марина
2005-09-14 15:15
2005.10.02
Не подскажете как генерировать случайные числа?


6-1118333564
olevacho_
2005-06-09 20:12
2005.10.02
Отсылка сообщения на комп в локальной сети


14-1125912858
badevlad
2005-09-05 13:34
2005.10.02
Участие в проекте


1-1126685990
john_mag
2005-09-14 12:19
2005.10.02
Button or BitBtn