Using InstallUtil to install a Windows service with startup parameters
Asked Answered
D

2

14

I am using InstallUtil to install my service and I just cannot figure out how to specify the startup parameters for it!

Here is my Installer subclass:

[RunInstaller(true)]
public class ServerHostInstaller : Installer
{
  private ServiceInstaller m_serviceInstaller;
  private ServiceProcessInstaller m_serviceProcessInstaller;
  private static string s_usage = "Usage:\ninstallutil /i /username=<user_name> /password=<user_password> NCStub.Server.Host.exe";

  public ServerHostInstaller()
  {
    m_serviceInstaller = new ServiceInstaller();
    m_serviceInstaller.ServiceName = Program.ServiceName;
    m_serviceInstaller.DisplayName = Program.ServiceName;
    m_serviceInstaller.StartType = ServiceStartMode.Automatic;

    m_serviceProcessInstaller = new ServiceProcessInstaller();
    m_serviceProcessInstaller.Account = ServiceAccount.User;

    Installers.Add(m_serviceInstaller);
    Installers.Add(m_serviceProcessInstaller);
  }

  public override void Install(IDictionary stateSaver)
  {
    base.Install(stateSaver);

    string userName = this.Context.Parameters["username"];
    if (userName == null)
    {
      Console.WriteLine(s_usage);
      throw new InstallException("Missing parameter 'username'");
    }

    string userPass = this.Context.Parameters["password"];
    if (userPass == null)
    {
      Console.WriteLine(s_usage);
      throw new InstallException("Missing parameter 'password'");
    }

    m_serviceProcessInstaller.Username = userName;
    m_serviceProcessInstaller.Password = userPass;
  }
}

Can anyone indicate how do I specify the service startup parameters?

Diastrophism answered 1/2, 2011 at 12:29 Comment(0)
D
15

Found it.

I have rewritten the Install method like so:

public override void Install(IDictionary stateSaver)
{
  string userName = this.Context.Parameters["username"];
  if (userName == null)
  {
    Console.WriteLine(s_usage);
    throw new InstallException("Missing parameter 'username'");
  }

  string userPass = this.Context.Parameters["password"];
  if (userPass == null)
  {
    Console.WriteLine(s_usage);
    throw new InstallException("Missing parameter 'password'");
  }

  m_serviceProcessInstaller.Username = userName;
  m_serviceProcessInstaller.Password = userPass;

  var path = new StringBuilder(Context.Parameters["assemblypath"]);
  if (path[0] != '"')
  {
    path.Insert(0, '"');
    path.Append('"');
  }
  path.Append(" --service");
  Context.Parameters["assemblypath"] = path.ToString();
  base.Install(stateSaver);
}

Although, I give the predefined command line parameters (--service), the code is easily adaptable to pass real command line arguments, just use the same pattern for passing the username and password parameters.

Diastrophism answered 1/2, 2011 at 13:57 Comment(5)
This approach also works if you attach a handler to the BeforeInstall event of the service installer object rather than overriding the Install method.Habitation
Actually no it doesn't. It ought to and I'm fairly sure it used to but I just checked and it doesn't. Stick with the override version.Habitation
I have the same solution to pass credentials to my installer. The problem is that the log file contains your credentials aswell, which is a big problem in my opinion. Do you have an idea how to disable the writing of "Affected parameters are:" in the logfile? I don't want to disabled the complete logfile!Glee
@FlorianGerhardt - Nope. I have moved to Java and Javascript since then, no .NET for the past half a year. Sorry, man.Diastrophism
This solution does not work. It produces following command like for service: ""C:\folder\file.exe" --service"Activist
T
4

I know this is an old post but thought I'd post my response. I did this in a .net 4 service using the BeforeInstall event.

The ServiceProcessInstaller's BeforeInstall event:

private void serviceProcessInstaller1_BeforeInstall(object sender, InstallEventArgs e)
{
    System.ServiceProcess.ServiceProcessInstaller installer = sender as System.ServiceProcess.ServiceProcessInstaller;

    if (installer != null)
    {
        //Get the existing assembly path parameter
        StringBuilder sbPathWIthParams = new StringBuilder(installer.Context.Parameters["assemblypath"]);

        //Wrap the existing path in quotes if it isn't already
        if (!sbPathWIthParams[0].Equals("\""))
        {
            sbPathWIthParams.Insert(0, "\"");
            sbPathWIthParams.Append("\"");
        }

        //Add desired parameters
        sbPathWIthParams.Append(" test");

        //Set the new path
        installer.Context.Parameters["assemblypath"] = sbPathWIthParams.ToString();
    }
}

The installed service looks as follows: enter image description here

It executes fine, and I can examine the parameters from within the main function of the service.

Test answered 17/9, 2015 at 20:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.