首页  编辑  

服务和普通应用两栖程序

Tags: /超级猛料/Core.驱动,VxD,服务/   Date Created:

采取下面的方法,可以作一个两栖服务程序

附件是一个简单模版,可以直接使用,包括重复性检测。

首先做一个公共模块,即服务和程序都需要用到的一个部分,以便程序和服务调用。

然后建立窗体,和普通程序一样,然后调用公共模块的功能,然后添加一个Service,同样也调用类似的功能,最后修改Project源代码,修改类似下面:

 if ParamStr(1) = '/DEBUG' then

 begin

   Forms.Application.Initialize;

   Forms.Application.CreateForm(TForm1, Form1);  ///普通窗体

   Forms.Application.CreateForm(TdmWeb, dmWeb);  /// 公共模块

   Forms.Application.Run;

 end

 else

 begin

   SvcMgr.Application.Initialize;

   SvcMgr.Application.CreateForm(TSvrWeb, SvrWeb);  /// 服务窗体

   SvcMgr.Application.CreateForm(TdmWeb, dmWeb);    /// 公共模块

   SvcMgr.Application.Run;

 end;

这样,带/DEBUG参数,则以普通程序方式运行,若用服务管理器来运行,则作为服务运行。

例如公共模块:

dmPublic,提供Start,Stop方法。

在主窗体中,调用dmPublic.Start,dmPublic.Stop方法。

同样在Service中,调用dmPublic.Start,dmPublic.Stop方法。

---------------------------------------

Here's what you need to do to make a Delphi service use it....

Original service project file looks like this...

program TestService;

uses

 SvcMgr,

 TestServiceImpl in 'TestServiceImpl.pas' {Service1: TService};

{$R *.RES}

begin

 Application.Initialize;

 Application.CreateForm(TService1, Service1);

 Application.Run;

end.

Modify the project file to look like this...

program TestService;

uses

 SvcMgr,

 unitDebugService,

 TestServiceImpl in 'TestServiceImpl.pas' {Service1: TService};

{$R *.RES}

var debugMode : boolean;

begin

 debugMode := False;

 if (paramCount > 0) and (SameText (ParamStr (1), '-DEBUG')) then

 begin

   FreeAndNil (Application);

   Application := TDebugServiceApplication.Create(nil);

   debugMode := True;

 end;

 Application.Initialize;

 Application.CreateForm(TService1, Service1);

 // Service1.DebugMode := debugMode;  Optionally create a global

 //                                   DebugMode variable in your

 //                                   service, and set it here.

 Application.Run;

end.

---------------------------------------

unit unitDebugService;

interface

uses Windows, Messages, Consts, Classes, SysUtils, Forms, SvcMgr;

type

//---------------------------------------------------------------------

// TDebugServiceApplication class

TDebugServiceApplication = class (TServiceApplication)

private

 procedure OnExceptionHandler(Sender: TObject; E: Exception);

public

 procedure Run; override;

 destructor Destroy; override;

 procedure TerminateThreads (all : boolean);

end;

//---------------------------------------------------------------------

// TDebugServiceThread class

TDebugServiceThread = class (TThread)

private

 fService : TService;

 procedure ProcessRequests(WaitForMessage: Boolean);

protected

 procedure Execute; override;

public

 constructor Create (AService : TService);

end;

implementation

{ TDebugServiceApplication }

destructor TDebugServiceApplication.Destroy;

begin

try

 inherited;

except

 MessageBeep ($ffff);

end

end;

(*----------------------------------------------------------------------*

| procedure TDebugServiceApplication.OnExceptionHandler                |

|                                                                      |

| Handler for VCL exceptions                                           |

|                                                                      |

| Parameters:                                                          |

|   Sender: TObject; E: Exception                                      |

*----------------------------------------------------------------------*)

procedure TDebugServiceApplication.OnExceptionHandler(Sender: TObject; E: Exception);

begin

 DoHandleException(E);

end;

(*----------------------------------------------------------------------*

| procedure TDebugServiceApplication.Run                               |

|                                                                      |

| Run the service

*----------------------------------------------------------------------*)

procedure TDebugServiceApplication.Run;

var

 i : Integer;

 service : TService;

 thread : TThread;

begin

 Forms.Application.OnException := OnExceptionHandler;

 try

 // Create a TDebugServiceThread for each of the services

   for i := 0 to ComponentCount - 1 do

     if Components [i] is TService then

     begin

       service := TService (Components [i]);

       thread := TDebugServiceThread.Create(service);

       thread.Resume;

       service.Tag := Integer (thread);

     end;

 // Run the 'service'

   while not Forms.Application.Terminated do

     Forms.Application.HandleMessage;

 // Terminate each TDebugServiceThread

   TerminateThreads (True)

 finally

 end;

end;

{ TDebugServiceThread }

(*----------------------------------------------------------------------*

| constructor TDebugServiceThread.Create                               |

|                                                                      |

| Constructor for TDebugServiceThread                                  |

*----------------------------------------------------------------------*)

constructor TDebugServiceThread.Create(AService: TService);

begin

 fService := AService;

 inherited Create (True);

end;

(*----------------------------------------------------------------------*

| procedure TDebugServiceThread.Execute                                |

|                                                                      |

| 'Execute' method fot TDebugServiceThread.  Process messages          |

*----------------------------------------------------------------------*)

procedure TDebugServiceThread.Execute;

var

 msg: TMsg;

 Started: Boolean;

begin

 PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE); { Create message queue }

 try

   Started := True;

   if Assigned(FService.OnStart) then FService.OnStart(FService, Started);

   if not Started then

   begin

     PostMessage (Forms.Application.Handle, WM_QUIT, 0, 0);

     ProcessRequests (True);

     Exit

   end;

   try

     if Assigned(FService.OnExecute) then

       FService.OnExecute(FService)

     else

       ProcessRequests(True);

     ProcessRequests(False);

   except

     on E: Exception do

       FService.LogMessage(Format(SServiceFailed,[SExecute, E.Message]));

   end;

 except

   on E: Exception do

   begin

     FService.LogMessage(Format(SServiceFailed,[SStart, E.Message]));

     PostMessage (Forms.Application.Handle, WM_QUIT, 0, 0);

   end

 end;

end;

(*----------------------------------------------------------------------*

| procedure TDebugServiceThread.ProcessRequests                        |

|                                                                      |

| 'ProcessRequests' method.  do a message loop.                        |

*----------------------------------------------------------------------*)

procedure TDebugServiceThread.ProcessRequests(WaitForMessage: Boolean);

var

 msg: TMsg;

 Rslt, stopped: Boolean;

begin

 while True do

 begin

   if Terminated and WaitForMessage then break;

   if WaitForMessage then

     Rslt := GetMessage(msg, 0, 0, 0)

   else

     Rslt := PeekMessage(msg, 0, 0, 0, PM_REMOVE);

   if not Rslt then    // No message received, or WM_QUIT

   begin

     if not WaitForMessage then

       break;

                       // WM_QUIT received.  Terminate loop - if we're allowed

     stopped := True;

     if Assigned (fService.OnStop) then

       fService.OnStop (fService, stopped);

     if stopped then

       break

   end

   else

   DispatchMessage(msg);

 end;

end;

procedure TDebugServiceApplication.TerminateThreads (all : boolean);

var

 i, n : Integer;

 service : TService;

 thread : TThread;

begin

 if all then

   n := 0

 else

   n := 1;

 for i := ComponentCount - 1 downto n do

   if Components [i] is TService then

   begin

     service := TService (Components [i]);

     thread := TThread (service.Tag);

     if Assigned (thread) then

     begin

       PostThreadMessage (thread.ThreadID, WM_QUIT, 0, 0);

       thread.WaitFor;

       FreeAndNil (thread)

     end;

     service.Tag := 0;

   end;

end;

end.

SvrDesk.zip (11.1KB)