Definitely under the note to self category this one...

I've been working with installing a service and took the base code from our platform. Part of the command line specifies a parameter to be used within the installer, but no matter what I did I could not get the parameter to be picked up.

An example of the installation command line is
"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\installUtil.exe" "C:\Services\MyService.exe" /SERVICENAME="My Special Service"
which, at least in theory, allows the service to be created so that in the Services dialog it is listed under the name "My Special Service"

A quick google with the right keywords and I stumbled across The curious case of InstallUtil and service parameters which both explains the situation and provides a lovely working solution.

In my case, the code was even simpler than the example as I was specifically looking for only one parameter, the service name, and so my OnBeforeInstall and OnBeforeUninstall become

protected override void OnBeforeInstall(System.Collections.IDictionary savedState)
{
   base.OnBeforeInstall(savedState);
   SetServiceNameFromCommandLineParameter();
}

protected override void OnBeforeUninstall(System.Collections.IDictionary savedState)
{
   base.OnBeforeUninstall(savedState);
   SetServiceNameFromCommandLineParameter();
}

where SetServiceNameFromCommandLineParameter is :

void SetServiceNameFromCommandLineParameter()
{
   const string SERVICE_NAME = "SERVICENAME";

   String[] args = System.Environment.GetCommandLineArgs();
   String no_log_file = null;
   InstallContext tmp_ctx = new InstallContext(no_log_file, args);

   string serviceName = tmp_ctx.Parameters[SERVICE_NAME];

   if (serviceName == null)
   {
      throw new ApplicationException(string.Format("{0} undefined", SERVICE_NAME));
   }

//Set service name
   this.serviceInstaller1.DisplayName = serviceName ;
   this.serviceInstaller1.ServiceName = serviceName;
}

where serviceInstaller1 is defined as private ServiceInstaller serviceInstaller1;

As to why this works in the base code, but doesn't for mine I have no idea, but I have at least got it working now