用Delphi编写Windows服务(Service)

    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(
' SoftWareBHomeEducation ' ,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;
  
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页