Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a Windows service with parameters?

I have written a Windows service, of which I want to have 1 instance running per customer. This is because the customers each have their own DB with identical schemas; the only difference between the Windows services is that they will each have a different parameter corresponding to the customer DB that they're designated to serve. (And I can't have one service with multiple worker threads, because the DB connection uses a static variable, which I can't fiddle with across threads.)

I found this neat little tutorial about how to make a Windows Service, but it only shows me how to set it up for a single service. I want to set up n instances of the service, each one with a display name that includes the customer name, running with the command line parameter that denotes the customer ID.

The tutorial linked above has a class called MyWindowsServiceInstaller, which installs the windows service on the local system, and I'm guessing this would be a logical place to set up a foreach loop through all my customers, setting up one service for each. But I can't see anywhere on the interfaces provided that would allow me to set up a command line parameter for the new service.

How do you do it?

like image 366
Shaul Behr Avatar asked Feb 11 '10 10:02

Shaul Behr


People also ask

How do I pass parameters to a Windows service?

You can pass parameters on startup like this: Right click on MyComputer and select Manage -> Services and Applications -> Services. Right click on your service, select Properties and you should then see the Start Parameters box under the General tab.

How do I create a Windows service from the command line?

The SC Create command uses the following format: sc create serviceName binpath= "path\to\service-wrapper-7.4.exe" optionName= optionValue ... where: create is the command to be run by SC (this command name is mandatory to create a service).

What is start parameters in service?

Startup parameters change the behavior of the Service Manager server. You can always set a startup parameter from the server's operating system command prompt.


4 Answers

All I wanted was to send one parameter to the service I have created. As it turns out, all you have to do is (carefully!) edit the registry at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ and add the parameter in ImagePath, after the quotes.

Eg. ImagePath Value Data: "C:\Program Files\myservice\myservice.exe" param1

I found the solution in this link http://social.msdn.microsoft.com/Forums/is/csharpgeneral/thread/38242afa-7e40-4c06-975e-aa97d3cc782f

like image 63
Ricardo Appleton Avatar answered Oct 23 '22 17:10

Ricardo Appleton


Wil Peck wrote a good article about how to install multiple instances of a windows service on a single box. The basic idea is that you have to trick the installer into thinking they are different services by giving them different names.

Having said that, it seems like it would be easier (and more maintainable) to redesign your database connection code so that it can support multiple worker threads.

like image 44
Jeff Sternal Avatar answered Oct 23 '22 18:10

Jeff Sternal


You basically need to install the service several times, and customise it with it's exe.config file.

Alternatively, you can have one service that runs different worker threads for each client.

Update

exe.Config is an Application Configuration File

I have no idea how to use that installer component to install several instances of the service, I wasn't aware you could.

Where we need several instances of one of our services to run on one machine, we actually only install it once, then literally copy the installed folder and change the exe name for the second instance. The second instance is then configured in it's own Application Configuration File.

like image 1
2 revs Avatar answered Oct 23 '22 17:10

2 revs


As far as I known it is impossible to provide startup parameters using either ServiceInstaller, ServiceProcessInstaller or installutil. However, it is possible to provide startup parameters using some COM api's from advapi.dll (check the left menu). A complete collection of the required calls can be found here. It's a class (also) called ServiceInstaller that contains the required external methods and some utility methods.

You'd want to use the utility method InstallAndStart. It accepts a service name, a display name and a path to the executable that represents your Windows service. You can call it like this:

InstallAndStart("MyService", "My Service For User 1",
                "c:\\pathtoexe\MyService.exe user1");

If you have the following service the parameter startupParam will receive the value user1.

class Program : ServiceBase
{
    private string startupParam;

    static void Main(string[] args)
    {
        string arg = args[0];
        ServiceBase.Run(new Program(arg));
    }

    public Program(string startupParam)
    {
        this.ServiceName = "MyService";
        this.startupParam = startupParam;
    }
    ...
}
like image 1
Ronald Wildenberg Avatar answered Oct 23 '22 19:10

Ronald Wildenberg