- 註冊時間
 - 2006-3-13 
 - 最後登錄
 - 2025-7-23 
 - 在線時間
 - 675 小時 
 - 閱讀權限
 - 200 
 - 積分
 - 417 
 - 帖子
 - 1109 
 - 精華
 - 0 
 - UID
 - 2 
  
 
 
 
    
 | 
 
Windows的服务是一个比较实用的功能,你的程序可以在Windows未进行登录的时候就开始运行,不受用户注销的影响,也不容易被用户误关闭。 
 
但是编写服务也许不是一件容易的事情,幸好Delphi给我们提供了一个模板,可以很容易的编写一个标准的Windows服务程序。 
 
首先,在 Delphi 内新建一个 Service Application。 
 
此时,Delphi 已经给我们建好了一个Service程序的框架,我们只需要把我们的代码加到合适的位置就行了。 
 
一般情况下,Service内需要一个线程来不断的工作,也许定时器也可以,但线程工作起来更好。 
 
Delphi会生成一个可视化的Service容器,你可以一些必要的控件在它上面,但是由于它是服务程序,是没有界面显示的,因此不建议在上面安放Edit之类的控件,服务只是应该做处理工作的,显示界面应该由其它的程序来完成。Service控件的DisplayName属性是显示在管理工具-》服务的左边的名称的内容,而Name属性则是服务名称,当你用命令提示符来启动、停止服务时,就需要用到。 
 
在事件OnStart内,我们应该完成启动线程的工作。 
 
如: 
 
- procedure TS2HConv.ServiceStart(Sender: TService;var Started: Boolean);
 
 - var 
 
 -   Reg:TRegistry;
 
 -   LogFileName,LogPath:String;
 
 -   slTemp:TStringList;
 
 - begin
 
 -   CoInitialize(nil);
 
 -   Reg := TRegistry.Create;
 
 -   Reg.RootKey := HKEY_LOCAL_MACHINE;
 
 -   Reg.OpenKey('\SoftWare\BHome\Education', True);
 
 -   LogPath := Trim(Reg.ReadString('LogPath'));
 
 -   SourceConnStr := Trim(Reg.ReadString('SourceConnStr'));
 
 -   if Trim(LogPath) = '' then
 
 -     LogPath := 'C:\';
 
 -   Reg.CloseKey;
 
 -   Reg.Free;
 
  
-   if RightStr(LogPath,1) <> '\' then
 
 -     LogPath := LogPath+'\';
 
 -   LogFileName := LogPath + FormatDateTime('yyyymmdd', Now) + 'Log.txt';
 
 -   Try
 
 -     if not FileExists(LogFileName) then
 
 -     begin
 
 -       slTemp := TStringList.Create;
 
 -       slTemp.Clear;
 
 -       slTemp.SaveToFile(LogFileName);
 
 -       slTemp.Free;
 
 -     end;
 
 -     AssignFile(LogFile, LogFileName);
 
 -     Append(LogFile);
 
 -   Except
 
 -     Started := False;
 
 -   Exit;
 
 - End;
 
  
- Started := True;
 
  
- try
 
 -   AC_Source := TADOConnection.Create(nil);
 
 -   Q_Source := TADOQuery.Create(nil) ;
 
 -   Q_Source.Connection := AC_Source;
 
  
-   try
 
 -     AC_Source.Close;
 
 -     AC_Source.ConnectionString:=SourceConnStr;
 
 -     AC_Source.Open;
 
 -     SYSLog('与源数据库连接成功!');
 
 -     DBOK:=True;
 
 -   Except
 
 -   on E:Exception do begin
 
 -     DBOK:=False;
 
 -     SYSLog('数据库连接失败!'+E.Message);
 
 -   end;
 
 - End;
 
  
-   MyPHSThread := TPHSSendThread.Create();
 
 -   MyPHSThread.FreeOnTerminate := True;
 
 -   MyPHSThread.Priority := tpLower;
 
 - end;
 
  複製代碼 
在OnStop事件内,我们应该停止线程,并释放打开的资源,需要注意的是当你停止线程时,一般用Terminate方法,在线程内用Terminated属性来判断是否需要结束线程,而由于是线程,和主进程是时间运行的,有可能你刚好在进行Terminate时,线程已经刚进行过Terminated判断,正在进行比较费时的处理工作,而此时主进程立即执行Terminate后就进行释放资源的工作时,会造成线程执行错误,因此应该等到线程真正的正确停止后,主进程才能进行资源释放工作。 
 
如: 
 
- procedure TS2HConv.ServiceStop(Sender: TService;var Stopped: Boolean);
 
 - begin
 
 -   try
 
 -     MyPHSThread.Terminate;
 
 -     while __ThreadIsRun do
 
 -     sleep(1000);
 
 -     AC_Source.Close;
 
 -     CloseFile(LogFile);
 
 -     FreeAndNil(Q_Source);
 
 -     FreeAndNil(AC_Source);
 
 -     CoUnInitialize;
 
 -   Except
 
 -   End;
 
 -   Stopped:=True;
 
 - end; 
 
  複製代碼 |   
 
  
 |