I have a service application built in Delphi that works great. It does exactly what I want it to do and all is happy. All is fine until I want to run two (or more) instanc
The accepted answer above was awfully helpful.
Code I used:
procedure TService1.ServiceAfterInstall(Sender: TService);
begin
//http://stackoverflow.com/questions/612587/is-it-possible-to-install-multiple-instances-of-the-same-delphi-service-applicati
//http://www.c-sharpcorner.com/UploadFile/timosten/DynamicServiceInCSharp11262005062503AM/DynamicServiceInCSharp.aspx?ArticleID=4d5020e4-7317-425c-ab29-5bf37a1db421
//http://support.microsoft.com/kb/137890
SaveRegSetting('\SYSTEM\CurrentControlSet\Services\' + Name, 'ImagePath', ParamStr(0) + ' --name=' + Name, HKEY_LOCAL_MACHINE)
end;
procedure TService1.ServiceCreate(Sender: TObject);
begin
Name := Trim(FCommandLineOptions.Values['name']);
DisplayName := Name;
end;
SaveRegSetting is my own procedure and FCommandLineOptions is an object that tokenises the command line parameters.
You can create your service with multiple threads internally, each one acting like it's own version/copy of the service. You control it with the Service Controller API, IIRC.
Insted of hacking the registry, I would recommend using the following guidance and use the Windows Service Controller (sc.exe) command line interface:
When creating a service with sc.exe how to pass in context parameters?
(EDIT: Do use the code as suggested to obtain the Name & DisplayName properties, just don't install your service using the /install switch for your service executable.)
You haven't made it clear what you have tried to change in the TService subclass.
Have you added a "BeforeInstall" handler?
Something like:
procedure TServiceMain.ServiceLoadInfo(Sender : TObject);// new method, not an override
begin
Name := ParamStr(2);
DisplayName := ParamStr(3);
end;
procedure TServiceMain.ServiceBeforeInstall(Sender: TService);
begin
ServiceLoadInfo(Self);
end;
procedure TServiceMain.ServiceCreate(Sender: TObject);
begin
ServiceLoadInfo(Self);
end;
If you do this regularly, subclass TService to do thie in the Constructor instead.
You should do the same in the BeforeUninstall as well - point both events at the same method.
C:\>servicename /install MyService "My Service Description"
Well yes it is possible to install multiple instances of the same service, you simply need to dynamically alter the name at install time (not runtime) however this does not make it desireable. (there is some sample code on Code project http://www.codeproject.com/KB/dotnet/MultipleInstNetWinService.aspx)
I would however be inclined to rethink your approach, service processes themselves are really meant to be singleton, if you need multiple instances of a process being run, maybe your service should just control and manage the multiple processes rather than being the process.
Wrap all of your code into a class that inherits from TThread.
When your service starts it will read a number from a settings file or from the registry and create that many instances of your class.
Each instance runs independently.
To change the number of running instances you could shut down the service, edit the setting (in a file or registry) and restart the service.