1

I want to deploy a single exe which provides a web service, and be able to start it multiple times (each as a separate Windows service). Each instance of the exe needs to be able to load a different configuration file (e.g. so it can listen on a different port, or use a different database).

Ideally, I don't want to have to install the exe in multiple folders, just have multiple configuration files.

However there doesn't seem to be a way of finding which service name Windows is starting.

I have looked at How can a Windows Service determine its ServiceName? but it doesn't seem to work for me, because during startup the process id for the service being started is 0.

I guess I am asking too soon or something. My code does the following:

Main sets the current directory and constructs a WebService object (a subclass of ServiceBase)

The WebService object constructor now needs to set its ServiceName property, and uses the code in How can a Windows Service determine its ServiceName? to try to find the correct name. However, at this point the processid of the correct servicename is still 0.

Following this, Main will build an array of (1) ServiceBase containing the WebService object, and call ServiceBase.Run on the array. The service name needs to be correct by this point, because it may not be changed once the service is running.

Community
  • 1
  • 1
Nikki Locke
  • 2,759
  • 6
  • 29
  • 53

1 Answers1

0

I found an alternative way to achieve my goal, after reading https://stackoverflow.com/a/7981644/862344

During the install of the webservice, the install program (which happens to be the same program, but with a command-line parameter of "install") knows which settings file to use (because there is a command-line parameter "settings=").

The linked question shows there is a simple way to get that command-line parameter passed to the service every time it starts, by overriding the OnBeforeInstall (and OnBeforeUninstall) methods of the Installer class.

protected override void OnBeforeInstall(System.Collections.IDictionary savedState) {
    if (HasCommandParameter("settings")) {
        // NB: Framework will surround this value with quotes when storing in registry
        Context.Parameters["assemblypath"] += "\" \"settings=" + CommandParameter("settings");
    }
    base.OnBeforeInstall(savedState);
}

protected override void OnBeforeUninstall(System.Collections.IDictionary savedState) {
    if (HasCommandParameter("settings")) {
        // NB: Framework will surround this value with quotes when storing in registry
        Context.Parameters["assemblypath"] += "\" \"settings=" + CommandParameter("settings");
    }
    base.OnBeforeUninstall(savedState);
}

I have found that something in the framework surrounds the Context.Parameters["assemblypath"] value with quotes before storing it in the registry (at HKLM\System\CurrentControlSet\Services\\ImagePath), so it is necessary to add '" "' between the existing value (which is the exe path) and the parameter.

Community
  • 1
  • 1
Nikki Locke
  • 2,759
  • 6
  • 29
  • 53