中国程序员联盟 正在重新改版中ing 不便之处还请见谅 改版后将内容涉及java delphi .net php
 
  首页 | 数据库开发 | 网络通讯 | 多线程 | 多媒体开发 | 图像处理 | 程序人生 | 系统函数 | 控件开发 | Web服务
 
  当前位置:笨鱼delphi技术网>系统函数>文章内容

delphi 通过线程实现Windows服务

来源:国外 关于:Kim Sandell 发布时间:2007-07-03   [收藏] [推荐]
Problem/Question/Abstract:
Delphi 5&6 has a template project for services, but it is incomplete. This example builds on that template and completes the service. It also shows how to start a thread that beeps every 2 seconds. You can use this as a base when developing servers as services.
Answer:
This example shows how to use the service template in delphi, taking it a step further and making a complete example. The source for this is included in the ntservice.zip file.
Coded under D6, but works for D5 if you copy the source parts after creating a template service.
Below are all the source files listed one by one.
To test the source, create a Service with Delphi, and pase these sources on top of the automatically generated source.
program NTService;
uses
  SvcMgr,
  NTServiceMain in 'Units\NTServiceMain.pas' {ExampleService: TService},
  NTServiceThread in 'Units\NTServiceThread.pas';
{$R *.RES}
begin
  Application.Initialize;
  Application.CreateForm(TExampleService, ExampleService);
  Application.Run;
end.
{*
  Windows Service Template
  ========================
  Author          Kim Sandell
                  emali:
kim.sandell@nsftele.com
  Disclaimer      Freeware. Use and abuse at your own risk.
  Description     A Windows NT Service skeleton with a thread.
                  Works in WinNT 4.0, Win 2K, and Win XP Pro
                  The NTServiceThread.pas contains the actual
                  thread that is started under the service.
                  When you want to code a service, put the code in
                  its Execute() method.
  Example         To test the service, install it into the SCM with
                  the InstallService.bat file. The go to the Service
                  Control Manager and start the service.
                  The Interval can be set to execute the Example Beeping
                  every x seconds. It depends on the application if it
                  needs a inerval or not.
  Notes           This example has the service startup options set to
                  MANUAL. If you want to make a service that starts
                  automatically with windows then you need to change this.
                  BE CAREFULT ! If your application hangs when running as a
                  service THERE IS NO WAY to terminate the application.
  History     Description
  ==========  ============================================================
  24.09.2002  Initial version
*}
unit NTServiceMain;
interface
uses
  Windows, Messages, SysUtils, Classes, SvcMgr,
  NTServiceThread;
type
  TExampleService = class(TService)
    procedure ServiceExecute(Sender: TService);
    procedure ServiceStart(Sender: TService; var Started: Boolean);
    procedure ServiceStop(Sender: TService; var Stopped: Boolean);
    procedure ServicePause(Sender: TService; var Paused: Boolean);
    procedure ServiceContinue(Sender: TService; var Continued: Boolean);
    procedure ServiceShutdown(Sender: TService);
  private
    { Private declarations }
    fServicePri: Integer;
    fThreadPri: Integer;
    { Internal Start & Stop methods }
    function _StartThread(ThreadPri: Integer): Boolean;
    function _StopThread: Boolean;
  public
    { Public declarations }
    NTServiceThread: TNTServiceThread;
    function GetServiceController: TServiceController; override;
  end;
var
  ExampleService: TExampleService;
implementation
{$R *.DFM}
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  ExampleService.Controller(CtrlCode);
end;
function TExampleService.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;
procedure TExampleService.ServiceExecute(Sender: TService);
begin
  { Loop while service is active in SCM }
  while not Terminated do
  begin
    { Process Service Requests }
    ServiceThread.ProcessRequests(False);
    { Allow system some time }
    Sleep(1);
  end;
end;
procedure TExampleService.ServiceStart(Sender: TService; var Started: Boolean);
begin
  { Default Values }
  Started := False;
  fServicePri := NORMAL_PRIORITY_CLASS;
  fThreadPri := Integer(tpLower);
  { Set the Service Priority }
  case fServicePri of
    0: SetPriorityClass(GetCurrentProcess, IDLE_PRIORITY_CLASS);
    1: SetPriorityClass(GetCurrentProcess, NORMAL_PRIORITY_CLASS);
    2: SetPriorityClass(GetCurrentProcess, HIGH_PRIORITY_CLASS);
    3: SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
  end;
  { Attempt to start the thread, if it fails free it }
  if _StartThread(fThreadPri) then
  begin
    { Signal success back }
    Started := True;
  end
  else
  begin
    { Signal Error back }
    Started := False;
    { Stop all activity }
    _StopThread;
  end;
end;
procedure TExampleService.ServiceStop(Sender: TService;
  var Stopped: Boolean);
begin
  { Try to stop the thread - signal results back }
  Stopped := _StopThread;
end;
procedure TExampleService.ServicePause(Sender: TService; var Paused: Boolean);
begin
  { Attempt to PAUSE the thread }
  if Assigned(NTServiceThread) and (not NTServiceThread.Suspended) then
  begin
    { Suspend the thread }
    NTServiceThread.Suspend;
    { Return results }
    Paused := (NTServiceThread.Suspended = True);
  end
  else
    Paused := False;
end;
procedure TExampleService.ServiceContinue(Sender: TService;
  var Continued: Boolean);
begin
  { Attempt to RESUME the thread }
  if Assigned(NTServiceThread) and (NTServiceThread.Suspended) then
  begin
    { Suspend the thread }
    if NTServiceThread.Suspended then
      NTServiceThread.Resume;
    { Return results }
    Continued := (NTServiceThread.Suspended = False);
  end
  else
    Continued := False;
end;
procedure TExampleService.ServiceShutdown(Sender: TService);
begin
  { Attempt to STOP (Terminate) the thread }
  _StopThread;
end;
function TExampleService._StartThread(ThreadPri: Integer): Boolean;
begin
  { Default result }
  Result := False;
  { Create Thread and Set Default Values }
  if not Assigned(NTServiceThread) then
  try
    { Create the Thread object }
    NTServiceThread := TNTServiceThread.Create(True);
    { Set the Thread Priority }
    case ThreadPri of
      0: NTServiceThread.Priority := tpIdle;
      1: NTServiceThread.Priority := tpLowest;
      2: NTServiceThread.Priority := tpLower;
      3: NTServiceThread.Priority := tpNormal;
      4: NTServiceThread.Priority := tpHigher;
      5: NTServiceThread.Priority := tpHighest;
    end;
    { Set the Execution Interval of the Thread }
    NTServiceThread.Interval := 2;
    { Start the Thread }
    NTServiceThread.Resume;
    { Return success }
    if not NTServiceThread.Suspended then
      Result := True;
  except
    on E: Exception do
      ; // TODO: Exception Logging
  end;
end;
function TExampleService._StopThread: Boolean;
begin
  { Default result }
  Result := False;
  { Stop and Free Thread }
  if Assigned(NTServiceThread) then
  try
    { Terminate thread }
    NTServiceThread.Terminate;
    { If it is suspended - Restart it }
    if NTServiceThread.Suspended then
      NTServiceThread.Resume;
    { Wait for it to finish }
    NTServiceThread.WaitFor;
    { Free & NIL it }
    NTServiceThread.Free;
    NTServiceThread := nil;
    { Return results }
    Result := True;
  except
    on E: Exception do
      ; // TODO: Exception Logging
  end
  else
  begin
    { Return success - Nothing was ever started ! }
    Result := True;
  end;
end;
end.
{*
  A Windows NT Service Thread
  ===========================
  Author          Kim Sandell
                  Email:
kim.sandell@nsftele.com
*}
unit NTServiceThread;
interface
uses
  Windows, Messages, SysUtils, Classes;
type
  TNTServiceThread = class(TThread)
  private
    { Private declarations }
  public
    { Public declarations }
    Interval: Integer;
    procedure Execute; override;
  published
    { Published declarations }
  end;
implementation
{ TNTServiceThread }
procedure TNTServiceThread.Execute;
var
  TimeOut: Integer;
begin
  { Do NOT free on termination - The Serivce frees the Thread }
  FreeOnTerminate := False;
  { Set Interval }
  TimeOut := Interval * 4;
  { Main Loop }
  try
    while not Terminated do
    begin
      { Decrement timeout }
      Dec(TimeOut);
      if (TimeOut = 0) then
      begin
        { Reset timer }
        TimeOut := Interval * 4;
        { Beep once per x seconds }
        Beep;
      end;
      { Wait 1/4th of a second }
      Sleep(250);
    end;
  except
    on E: Exception do
      ; // TODO: Exception logging...
  end;
  { Terminate the Thread - This signals Terminated=True }
  Terminate;
end;
end.

[浏览: 次]   
上一篇:delphi 查找局域网机子   下一篇:delphi 得到连线用户名称域名主机名
[收藏] [推荐] [返回顶部] [打印本页] [关闭窗口]  
    评论加载中…
google adsense热点文章
·delphi Delphi中ShellExecute的妙用
·delphi 如何快速读取文本文件
·delphi 如何判断输入值是否中文
·delphi 在应用层截获键盘消息
·delphi delphi实现服务开启与关闭
·delphi 实时记录事件日志
·delphi 使MEMO自动滚动
·delphi 如何区分键盘两个Enter键
·delphi 切换界面的方法
·delphi 汉字输入法的编程及使用
·delphi Delphi程序输入法自动切换最简
·delphi 消息是由谁来发出又由谁来完成
     delphi技术网 | firefox 下载 | Avant Browser下载 | dedecms 技术网 | drupal 爱好者 | php 技术网
  Copyright@www.delphichm.com,2006-2009.All Rights Reserved.
 
程序员联盟 | delphi Java .net|QQ:707102932