3

After making a few various services in Delphi, I've realized that the TService is lacking some of the necessary things which should come with a service application, such as logging, exception handling, and the 'Description' property in the registry.

I was wondering if it's possible for me to make my own service shell such as TJDService which is inherited from a TService but with some additional things, such as a 'Description' property showing in the object inspector. Can I make my own service shell like this? I know I can make my own "default project" inheriting from a TService but that includes all my code with any new project.

When a new service is created, it should look like this:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, Vcl.SvcMgr,
  JDServices;

type
  TJDService1 = class(TJDService)
  private

  public
    function GetServiceController: TServiceController; override;
  end;

var
  JDService1: TJDService1;

implementation

{$R *.DFM}

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  JDService1.Controller(CtrlCode);
end;

function TJDService1.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;

end.

Same as a typical service, but using my TJDService instead of just TService.

Jerry Dodge
  • 26,858
  • 31
  • 155
  • 327
  • 1
    you are looking for RegisterCustomModule - http://docwiki.embarcadero.com/VCL/en/DesignIntf.RegisterCustomModule – OnTheFly Feb 12 '12 at 19:52
  • "Embarcadero Technologies does not currently have any additional information. Please help us document this topic by using the Discussion page!" And people wonder why other people complain about lack of delphi documentation :P – Jerry Dodge Feb 12 '12 at 19:56
  • 1
    Use RegisterCustomModule from a designtime package to make the Object Inspector aware of any published properties in your service class. If you don't need that then you can just ignore RegisterCustomModule. – David Heffernan Feb 12 '12 at 19:58
  • So which is more feasible: making a complete copy of `SvcMgr` unit and tweaking or just a class in another unit which inherits `TService`? – Jerry Dodge Feb 12 '12 at 20:00
  • The latter. Absolutely no need to modify VCL source for this. – David Heffernan Feb 12 '12 at 20:04
  • 4
    Personally I'd do away with the global variable and move the service controller methods into the TJDService class. I wouldn't bother with setting service properties in the IDE and would do it all in code. For something as basic and non-visual as a service I don't find the Object Inspector particularly valuable. Having it organised that way also gives me more control of the service instantiation and allows me to switch between a service and a standard desktop process, switched on a command line arg. The desktop process is simpler to debug. – David Heffernan Feb 12 '12 at 20:12
  • @JerryDodge, thats their template for generating documentation, but yeah, **Extending the IDE** part has been documented very poorly. Personally i keep respective help file from Delphi 7 around, because they dropped that from the documentation for BDS line. – OnTheFly Feb 12 '12 at 20:26
  • I've also been considering the ability for user interaction with the EXE, for example, being able to double-click on it to launch a small control window, which can be used to install/uninstall/configure the service. Not sure if that's possible, but that's worth another question. – Jerry Dodge Feb 12 '12 at 21:01

4 Answers4

6

Simple question with a simple answer. Yes you can do this. I do exactly this myself to share code between the various services that are implemented in my company's codebase.

RegisterCustomModule is the way to make your Description property show up in the Object Inspector. Having said that, I don't find the ability to set these service properties in the Object Inspector to be all that valuable. I would regard it perfectly acceptable to set them at runtime in code, but that decision is down to personal preference.

Even if you use RegisterCustomModule to make your service class known to the IDE, the default new service application will not use your service class. You can customise the default service application to your needs and then save it to the Object Repository.

My answer here shows how I implement an app that can be run as either a service or as a standard desktop process for debugging purposes.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I disapprove oversimplification approach this that, eg: TService lacks description support, we should fix that in the first hand. We can fix that once and then create our new service modules from repository w/o worrying about old Borland bugs. Re: debugging convenience: TService is merely a TDataModule, which can be added to any interactive w/o any problems. – OnTheFly Feb 12 '12 at 21:02
  • @user Yes, that's the point of the common base class that is derived from TService. It's exactly what I do in my code. Adding support for the service description was a motivation for my code too. I'm struggling to see what you are disapproving of. – David Heffernan Feb 12 '12 at 21:09
  • 2
    I disapproved "yep, me too!" style answer :p Only your comments reveals what your advice is leave existing solution as is. @kobik is agreeing with you on that, i do not. (meanwhile, title reads: "publish my own properties") – OnTheFly Feb 12 '12 at 21:20
  • 3
    @user I think my answer covers the whole question now. Thanks. – David Heffernan Feb 12 '12 at 21:27
  • 1
    @user Regarding debugging, it's hard to debug a service, in a different session with the process run by the SCM. You can't easily debug a standard delphi service project without making some mods to the project structure. – David Heffernan Feb 12 '12 at 21:50
  • @DavidHeffernan That's exactly one of the reasons I'd like to make my own service shell. I'm adding my own log file mechanism built into it which is attached to exception handlers. – Jerry Dodge Feb 12 '12 at 21:52
  • @user539484, I agree with your last comment. OP did ask "such as a 'Description' property showing in the **object inspector**". I only added a side comment of my own personal view of that issue. nothing more. – kobik Feb 12 '12 at 22:01
3

Yes you can and below link on how to do it

http://www.marcocantu.com/ddh/ddh15/ddh15e.htm

APZ28
  • 997
  • 5
  • 4
  • Cool, thats what i mean in the first comment! – OnTheFly Feb 12 '12 at 20:52
  • 2
    +1. good article. BUT (and this is only my own personal preference): I always try to avoid adding extra design stuff to the IDE, and use code at run-time. I would keep the code Jerry posted as is (looks good to me) and assign my properties and methods at run-time. – kobik Feb 12 '12 at 21:07
2

If you don't want to have to do the work yourself SvCom offers a nice set of tools for creating services in Delphi that provide far more than what's available out of the box.

Mike W
  • 1,276
  • 8
  • 10
1

I'm going to be a rebel here, but the easiest way to do this is make your own copy of SvcMgr and make the changes there. As long as you only make changes that are accessed at run-time, build and run with your own local copy of SvcMgr. I do this to change the basic exception handling and application logging that come with a service and you can download my copy of SvcMgr.pas from my web site.

This won't work if you need design-time changes, but pretty much everything you do at design-time you can do at run-time anyway. There are better solutions, but none faster and easier.

Misha
  • 1,816
  • 1
  • 13
  • 16
  • 1
    This becomes painful when you do a delphi upgrade and have to update the code and reimplement your mods. Sometimes you are forced to use this approach but surely it should be a last resort when no other solutions are viable? – David Heffernan Feb 12 '12 at 23:09
  • Not really - I have used this approach since Delphi 7 and it has taken a sum total of about 15 minutes to merge subsequent changes in. It is a risk management decision - if the unit is unlikely to change much this is the least effort approach. Most of us never have the time to do anything perfectly so my question would be why spend more than the necessary time to get a job done to spec? – Misha Feb 13 '12 at 02:37