DovetailConnect Blog

top-shelf-3-small

Here is another one where I post about something Josh and team did that I borrowed and am using to great effect. When a console app or a windows service needed we like to use TopShelf to get the job done. In this post I’ll show how to get two instances of a Windows service running on one machine using TopShelf.

Updated: As Mike points out in the comments below as of revision 46 Dru added a command line parameter to handle this scenario. Great! Much better than our hacky solution below (written before this revision). Please skip this post and just add a service install /instance:<name> argument at the command line to install additional windows services. Here is an example:

YourApplication.exe service install /instance:NumeroDos

Now back to the original post which should be ignored so stop reading now <grin>. Sigh, this is what I get for posting about something cool we did back in March.

Topshelf Basics

For a better introduction to TopShelf checkout Dru Sellers’s introductory post on TopShelf.

The code below is very close to the code we use to tell Topshelf how to setup one of our Windows services.

static void Main(string[] args){	var cfg = RunnerConfigurator.New(x =>	{		x.SetDisplayName("Dovetail Seeker Service");		x.SetServiceName("Seeker");		x.SetDescription("Indexing service for Dovetail Seeker.");		x.ConfigureService<SeekerService>("", c =>		{			c.WhenStarted(s => s.Start());			c.WhenStopped(s => s.Stop());		});	});	Runner.Host(cfg, args);}

All the application work is done by the SeekerService class. At runtime Topshelf makes it very easy to run an application as a console app or install it as a windows service.

Seeker.exe            #Runs as a consoleSeeker.exe /install   #installs the serviceSeeker.exe /uninstall #uninstalls the service

Why You Are Here

Unfortunately, Windows by default only allows one windows service with a given name. So the second time you try to install the application you’ll get an error.

2009-09-24 15:27:32,486 ERROR Topshelf.Internal.Actions.InstallServiceAction - The Seeker service has already been installed.

The solution is to change the name at runtime via configuration. Our solution was to add an application configuration setting defining the instance name of the service which then gets used at runtime. Here is the code above with a few changes.

static void Main(string[] args){	var instanceName = ConfigurationManager.AppSettings["WindowsServiceInstanceName"];	var cfg = RunnerConfigurator.New(x =>	{		x.SetDisplayName("Dovetail Seeker Service " + instanceName);		x.SetServiceName("Seeker" + instanceName);		x.SetDescription("Indexing service for Dovetail Seeker.");		x.ConfigureService<SeekerService>("", c =>		{			c.WhenStarted(s => s.Start());			c.WhenStopped(s => s.Stop());		});	});	Runner.Host(cfg, args);}

Here is a look at the app.config file with an alternate instance name defined:

<?xml version="1.0" encoding="utf-8" ?><configuration>  <appSettings file="applicationSettings.config">    <add key="WindowsServiceInstanceName" value="NumeroDos"/>  </appSettings></configuration>

Now installing the application does not give us an error.

>Seeker.exe /install

Beginning the Install phase of the installation.
2009-09-24 15:32:34,176 INFO  Topshelf.Internal.Hosts.HostServiceInstaller - Installing Service SeekerNumeroDos
Installing service DovetailSeeker...
Service SeekerNumeroDos has been successfully installed.
Creating EventLog source SeekerNumeroDos in log Application...

The Install phase completed successfully, and the Commit phase is beginning.

The Commit phase completed successfully.

The transacted install has completed.

 

Conclusion

Wee! We got multiple copies of our Windows service working on a single machine. When writing Windows services I recommend you check out Topshelf. Besides making it easy to work with Windows services. Topshelf works great in concert with IoC containers and allows you to easily get services on worker threads going about their business. But those details are for another post. Want to see more? Let me know.

share

Tags:

Comments

Re: Running Multiple Instances of a Windows Service Using TopShelf

@mike That revision came out after our grand Hack. Thank you for bringing this to our attention. I updated the post.

Post new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.