To the main page...The list of my products...Some texts...Sample applications, tips, tricks...If you need support...
 

 
Advanced interactive service
Step 1. Interactive service creation.

On this step the interactive service with one form will be created. It is not too difficult. The only thing is that the service application is multi-thread and VCL is not thread safe. Moreover the service thread is not the main thread of application so some efforts are necessary to allow the form be accessed from service.

One approach to this problem was considered earlier. It was based on idea of complete separation of form's VCL code by placing it into dll, compiled without run-time packages. Another approach will be used below. It idea is to avoid potential threading errors by placing all forms into main thread of application. It is possible because new method was added to the TNtServiceApplication class. This method is named "Synchronize" and is similar to TThread.Synchronize. The only difference is that the TThread.Synchronize can be called from the TThread only while TNtServiceApplication.Synchronize can be called from anywhere.

Well, let's create the interactive service with a form. Create the new SvCom service application, new SvCom service and one new form. Some property changes are necessary to the resulting application:

  • Turn on the Interactive property of the service module. It is necessary to allow the service to interact with interactive desktop. Note, that this property is used when the service is installed and modification of this property at run time will have no effect.
  • Turn off the auto-creation of form (Project -> Options -> Forms). The service will create it on start and it is not necessary to create the form each time when the application starts. Note that start of service and start of application are essentially different events.
  • Change the application into console mode (Project -> Options -> Linker -> Generate Console Application). It is necessary to avoid problems with closing window handles when logoff occurs.

The latest modification to be done is to add the form creating and releasing code. The service's OnStart and OnStop event handlers are acceptable for this purpose. The code modification should look like shown below.

























 
 



 
 
 



 
 




 
 

 

type
  TSvComEx16 = class(TNTService)
    procedure NtServiceStart(Sender: TNtService; var DoAction: Boolean);
    procedure NtServiceStop(Sender: TNtService; var DoAction: Boolean);
  private
    { Private declarations }
    procedure CreateServiceForm;
    procedure ReleaseServiceForm;
  public
    { Public declarations }
  end;

var
  SvComEx16: TSvComEx16;

implementation

{$R *.DFM}


procedure TSvComEx16.NtServiceStart(Sender: TNtService;
  var DoAction: Boolean);
begin
    Synchronize(CreateServiceForm);
end;

procedure TSvComEx16.CreateServiceForm;
begin
    ServiceMainForm:=TServiceMainForm.Create(nil);
    ServiceMainForm.Show;
end;

procedure TSvComEx16.ReleaseServiceForm;
begin
    ServiceMainForm.Release;
end;

procedure TSvComEx16.NtServiceStop(Sender: TNtService;
    var DoAction: Boolean);
begin
    Synchronize(ReleaseServiceForm);
end;

end.

As you see the CreateServiceForm and ReleaseServiceForm are not called directly. The Synchronize method is used to call them so they will be really called in the main application thread. It removes the thread safety problem.

The resulting service should look like this one (zip, 2 kb). On the next step we shall install and test this application.

<< | Index | Step 1 | Step 2 | Step 3 | Step 4 | Step 5 | Conclusions | >>
Add your comment | Read comments


 
© 1998-2001 Alexey Dynnikov
My ICQ # is 18267212