views:

2325

answers:

6

I have a Deplhi based Windows Service that, on installation, parses some command line arguments. I want those arguments to be added to the services command line (ImagePath value on the registry) so that the service is always started with them.

How can I accomplish this?

I want the regedit look like this:
at registry key HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\MyService

  • ImagePath = C:\Path\to\my\service.exe -some -arguments

Thanks

Update: The installation is done with >MyService.exe /install -some -arguments. Those arguments are the ones I want to persist in the command line.

Update: I found a solution by writing directly to the registry (see here), but I'd still like a more elegant solution, like using some TService property or something of that sort. Thanks!

A: 

I don't think you can make the service start with them, but if you store those parameters in the registry you can modify the program to on future starts always go and grab them. (i.e. if ParamCount = 0 then retrieve params from registry)

Zartog
You can surely make the service start with these params. The question is how to make the installer add them to the registry.
Uwe Raabe
+1  A: 

Service arguments can be passed in the lpBinaryPathName argument to the CreateService function. In Delphi's TService, this is called inside TServiceApplication.RegisterServices.InstallService, which you cannot override (easily).

Therefore, I suspect the easiest way to do this is going to be to handle the TService.AfterInstall event and update the registry yourself via ChangeServiceConfig.

Craig Stuntz
+4  A: 

Ok, after some research, I gave up on an elegant approach, and took the straight-forward path of writing directly to the registry.

To make things simple, I did this: I store the arguments I wanted to pass in variables on my TService. Then, I set the AfterInstall event to write directly into the registry (using a TRegistry object) the exact command line I wanted.

uses Registry;
procedure MyService.AfterInstall(Sender: TObject) ;
var
  reg:TRegistry;
begin
  reg := TRegistry.Create;
  try
    reg.RootKey := 'HKEY_LOCAL_MACHINE';
    if reg.OpenKey('SYSTEM\CurrentControlSet\Services\MyService', True) then
    begin
      reg.WriteExtendString ('ImagePath', ParamStr(0) + ' -some -arguments') ;
      reg.CloseKey;
    end;
  finally
    reg.Free;
  end;
end;

Not the elegant solution I was looking for, but it does the job.

Thanks for the other answers through!

Pablo
A: 

Pablo, I had the same question and couldn't find anything and went the route of editing the registry as well. In addition, I use Custom Actions also to create additional install directories and copy files (in C#). Your suggestion was helpful and I stopped looking for an "elegant" way as well. thanks

+1  A: 

I Just found out something little surprising, could be worthful to share.

You can specify parameters for Windows services in (at least) following ways:

  1. Enter it in the Service Manager GUI as "Startparameter".
  2. Pass it as arguments to: sc.exe YourService param1 param2
  3. Enter it in registry in entry ImagePath=..\YourService.exe param1 param2

In Delphi there are 2 ways to query application/service parameters:

  • System.ParamCount/System.ParamStr: This way you get the parameters of 3. above.
  • TService.ParamCount/TService.Param[]: This way you get the parameters of 1. and 2. above.
nang
1. Will work only when you start the service from the service manager, it is not persisted.
ldsandon
True. I have implemented persisting the parameters like described in the accepted answer above (AfterInstall). This answer was only intended as extra information.
nang
+1  A: 

You should use the SCM API to properly install the service and configure it. SC.EXE is a command line interface to the SCM API. You should not manipulate the registry directly in this situation, it works but it also depends which permission the service account has. Anyway I wonder why you need command line arguments if you embed them in the code - usually those arguments are set outside the service (by an installer, configurator, whatever) to change the service behaviour.

ldsandon
Good point about permission, didn't have that into account.About my need, my service doesn't have a configuration app, and installation is done with the /install param (I guess this way, if I have permission to create the reg key for the service, I also have permission to manually edit the key). Is these provided params that I want to persist. I don't exactly remember why now, but I think is because I wanted the service running many times with different parameters.
Pablo
ldsandon