Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Windows Services in One exe

I am trying to build several Windows services to do different things. For instance, I need Windows services that will:

  1. Send a daily report via email
  2. Periodically cleanup some archived info every 30 minutes
  3. etc.

The tasks I need the windows services to do are distinct so I don't really like the idea of having them all in one service.

What I've got so far is a project in Visual Studio 2008. I've created a windows service, I've set up a timer on the OnStart event (it just writes to a text file every 5 seconds for testing purposes). I then added an Installer to the project and when I run InstallUtil.exe, everything works fine.

The problem comes in when I add a second windows service to the same project. I set up the OnStart code again, with the same logging info (slightly different so I can tell which service is writing to the log). With the second windows service, I changed the Main event in Program.cs from:

    static void Main(string[] args)     {         ServiceBase[] ServicesToRun = new ServiceBase[]          {              new Service1()         };          ServiceBase.Run(ServicesToRun);     } 

to:

    static void Main(string[] args)     {         ServiceBase[] ServicesToRun = new ServiceBase[]          {              new Service1(),             new Service2()         };          ServiceBase.Run(ServicesToRun);     } 

At this point, there are no compile time errors, but the Service2 service never does anything...the logging task never fires.

I narrowed it down to the fact that the second service has no "Installer" associated with it. I then tried to add an Installer the way I did with the first service (i.e., right click on the service designer, and click "Add Installer"). Now, when I go to the ProjectInstaller.cs file, there is another serviceInstaller there (serviceInstaller2).

Now when I build the project and try to install the services, and I go to the "Services" control panel window, and I try to start Service1, I get the following error message:

Windows could not start the Service1 service on the Local Computer.

Error 1083: The executable program that this service is configured to run in does not implement the service.

I get the same error message if I try to start Service2 as well (with the exception that the error message identifies Service2, of course).

Is there something I am missing in order to get two services running from one exe?

like image 588
dp. Avatar asked May 03 '09 05:05

dp.


People also ask

How do I run multiple instances of Windows Service?

In order to add additional instance of a service to the Windows Service dialog box, each service must have a unique name. In order to achieve this you will need to use the Windows SC utility. The SC utility communicates with the Service Controller and installed services.

How do I install multiple instances of the same Windows Service?

You need to copy your service executable to a separate directory and use InstallUtil.exe to give it a different service name. From a command prompt, you'll need to use InstallUtil to install both instances of your service. For instructions on how to use InstallUtil, see Installer Tool (InstallUtil.exe).

Can two Windows services have the same name?

Answer. No, you should not have 2 services with the same name. It is mentioned in the Service Configuration Guide that service names should be unique. It it may be possible to create 2 services with the same name, but this can lead to problems in the future and is not a supported configuration.


1 Answers

I have figured out how to have one executable but two services. Each service installs to the service manager with its own name and ability to start/stop. I think this is what you're wanting, correct? Here is what I did:

  1. Created a service project.
  2. Added a second service to the same project (with a unique service name).
  3. Added an installer to both services (ServiceA and ServiceB).
  4. In the ProjectInstaller.Designer.vb file I changed the Me.Installers.AddRange line to show both of the service installers. (Me.ServiceInstaller1, Me.ServiceInstaller2)
  5. In the Main entry point of the main service (ServiceA in my case), I set the ServicesToRun variable to an array of ServiceBase containing all the services that I want it to run (ServiceA and ServiceB). This is an important step as the service manager sets a property based on the number of arguments here - either to allow multiple instances of the same exe or only a single instance.
  6. Add an installer project and use the output of Services.
  7. Add a custom action using the output from Services.

You can find the demo code here:
http://code.google.com/p/multi-service-install/

Enjoy!

like image 146
Scott Avatar answered Oct 08 '22 20:10

Scott