Converting a Delphi application to run as a service - is it necessary?

rossmcm picture rossmcm · Nov 5, 2010 · Viewed 14.2k times · Source

I have a delphi app that logs data from various places and writes the data to a file. The app has quite an extensive GUI to allow display of the data, configuration of the options, etc.

One user has requested that the app be changed to that it can be run as a service. His reasoning is that the app could then be started at boot time and run without any user being logged in and would be available regardless of who was logged in.

My question is this: Is there any other solution that would enable me to install the app as it now exists so that it would still run with no user logged in and still be available to all users?

My gut feeling is that converting the app to run as a service is not trivial. I assume you would need 2 apps - the "headless" service application, and a GUI that was run by users on demand that could interact with the service (comments welcome here also).

Answer

Wouter van Nifterick picture Wouter van Nifterick · Nov 5, 2010

I usually create my application in such a way that it can be started as a service or as a GUI, via a commandline switch /GUI.

When the application runs with a GUI, I instantiate and start the service class "manually".

Advantages:

  • It'll run the same code, making it very easy to debug the service. You can just put breakpoints and step through your code without having to "attach" to a running application.

  • Because of the GUI, you can see what your service would be doing, and interact with it, via listviews and buttons, even on remote servers where you don't have a debugger. Having to interact with your service via logs and configurations is crappy and slow.

Example dpr, from a project that works like this:

program xxxx;

uses 
  SysUtils,
  SvcMgr,
  .......;

{$R *.res}

begin
  GlobalAppId := 1;
  MapMatcherController := TMapMatcherController.Create(nil);
  try
    if FindCmdLineSwitch('GUI',['/','-'],True) then
    begin
      Forms.Application.Initialize;
      Forms.Application.MainFormOnTaskbar := True;
      Forms.Application.CreateForm(TfrmMain, frmMain);
      Forms.Application.Run;
    end
    else
    begin
      SvcMgr.Application.Initialize;
      SvcMgr.Application.CreateForm(TsrvMapMatcher2, srvMapMatcher2);
      SvcMgr.Application.Run;
    end;
  finally
    MapMatcherController.Free;
 end;
end.

Oh, another thing to keep in mind is that services usually run as a "system" user, which means you'll have different privileges and settings (for example drive letter mappings).