bestlong 怕失憶論壇

 

 

搜索
bestlong 怕失憶論壇 論壇 Delphi 用 Delphi 設計 Windows 服務(Service)
查看: 3880|回復: 0
go

用 Delphi 設計 Windows 服務(Service) [複製鏈接]

Rank: 9Rank: 9Rank: 9

1#
發表於 2006-8-4 13:56 |只看該作者 |倒序瀏覽 |打印
Windows的服务是一个比较实用的功能,你的程序可以在Windows未进行登录的时候就开始运行,不受用户注销的影响,也不容易被用户误关闭。

但是编写服务也许不是一件容易的事情,幸好Delphi给我们提供了一个模板,可以很容易的编写一个标准的Windows服务程序。

首先,在 Delphi 内新建一个 Service Application。

此时,Delphi 已经给我们建好了一个Service程序的框架,我们只需要把我们的代码加到合适的位置就行了。

一般情况下,Service内需要一个线程来不断的工作,也许定时器也可以,但线程工作起来更好。

Delphi会生成一个可视化的Service容器,你可以一些必要的控件在它上面,但是由于它是服务程序,是没有界面显示的,因此不建议在上面安放Edit之类的控件,服务只是应该做处理工作的,显示界面应该由其它的程序来完成。Service控件的DisplayName属性是显示在管理工具-》服务的左边的名称的内容,而Name属性则是服务名称,当你用命令提示符来启动、停止服务时,就需要用到。

在事件OnStart内,我们应该完成启动线程的工作。

如:

  1. procedure TS2HConv.ServiceStart(Sender: TService;var Started: Boolean);
  2. var
  3.   Reg:TRegistry;
  4.   LogFileName,LogPath:String;
  5.   slTemp:TStringList;
  6. begin
  7.   CoInitialize(nil);
  8.   Reg := TRegistry.Create;
  9.   Reg.RootKey := HKEY_LOCAL_MACHINE;
  10.   Reg.OpenKey('\SoftWare\BHome\Education', True);
  11.   LogPath := Trim(Reg.ReadString('LogPath'));
  12.   SourceConnStr := Trim(Reg.ReadString('SourceConnStr'));
  13.   if Trim(LogPath) = '' then
  14.     LogPath := 'C:\';
  15.   Reg.CloseKey;
  16.   Reg.Free;

  17.   if RightStr(LogPath,1) <> '\' then
  18.     LogPath := LogPath+'\';
  19.   LogFileName := LogPath + FormatDateTime('yyyymmdd', Now) + 'Log.txt';
  20.   Try
  21.     if not FileExists(LogFileName) then
  22.     begin
  23.       slTemp := TStringList.Create;
  24.       slTemp.Clear;
  25.       slTemp.SaveToFile(LogFileName);
  26.       slTemp.Free;
  27.     end;
  28.     AssignFile(LogFile, LogFileName);
  29.     Append(LogFile);
  30.   Except
  31.     Started := False;
  32.   Exit;
  33. End;

  34. Started := True;

  35. try
  36.   AC_Source := TADOConnection.Create(nil);
  37.   Q_Source := TADOQuery.Create(nil) ;
  38.   Q_Source.Connection := AC_Source;

  39.   try
  40.     AC_Source.Close;
  41.     AC_Source.ConnectionString:=SourceConnStr;
  42.     AC_Source.Open;
  43.     SYSLog('与源数据库连接成功!');
  44.     DBOK:=True;
  45.   Except
  46.   on E:Exception do begin
  47.     DBOK:=False;
  48.     SYSLog('数据库连接失败!'+E.Message);
  49.   end;
  50. End;

  51.   MyPHSThread := TPHSSendThread.Create();
  52.   MyPHSThread.FreeOnTerminate := True;
  53.   MyPHSThread.Priority := tpLower;
  54. end;
複製代碼

在OnStop事件内,我们应该停止线程,并释放打开的资源,需要注意的是当你停止线程时,一般用Terminate方法,在线程内用Terminated属性来判断是否需要结束线程,而由于是线程,和主进程是时间运行的,有可能你刚好在进行Terminate时,线程已经刚进行过Terminated判断,正在进行比较费时的处理工作,而此时主进程立即执行Terminate后就进行释放资源的工作时,会造成线程执行错误,因此应该等到线程真正的正确停止后,主进程才能进行资源释放工作。

如:

  1. procedure TS2HConv.ServiceStop(Sender: TService;var Stopped: Boolean);
  2. begin
  3.   try
  4.     MyPHSThread.Terminate;
  5.     while __ThreadIsRun do
  6.     sleep(1000);
  7.     AC_Source.Close;
  8.     CloseFile(LogFile);
  9.     FreeAndNil(Q_Source);
  10.     FreeAndNil(AC_Source);
  11.     CoUnInitialize;
  12.   Except
  13.   End;
  14.   Stopped:=True;
  15. end;
複製代碼
我是雪龍
http://blog.bestlong.idv.tw
http://www.bestlong.idv.tw
‹ 上一主題|下一主題

Archiver|怕失憶論壇

GMT+8, 2024-5-5 05:13 , Processed in 0.033189 second(s), 10 queries .

Powered by Discuz! X1.5

© 2001-2010 Comsenz Inc.