In many productions environments, Windows Services required to run under a privileged domain account. NET services consume the Installer Class foundation to control its installation flow. In most cases, your .NET service ends up packaged in MSI installer which automates the actions InstallUtil does in command line.
But what if you want to install a user account service automatically without bothering the user (other than the service account user\password entries) with post installation actions? Commonly MSI authors will use the ServiceInstall Table which allows runtime entry of username (‘StartName’ column) and password among other properties. However, in case the target service is always expected to run under a domain account, since Installutil.exe (Installer Tool) 4.0 there is another solution.
- First, the service must be set with user account. Fortunately this is the default behavior of ServiceProcessInstaller.
this.serviceProcessInstaller = new System.ServiceProcess.ServiceProcessInstaller();
this.serviceProcessInstaller.Account = new System.ServiceProcess.ServiceAccount.User;
this.serviceProcessInstaller.Password = null;
this.serviceProcessInstaller.Username = null;
- Next, test that InstallUtil installs the service successfully when run from the Visual Studio command prompt:
- Now we want to test unattended installation of the service.
- First we need to remove the service by adding the /u switch to the command: installutil.exe WindowsService1.exe /u
- And now repeat the test, this time without the prompt dialog: installutil.exe /username=[domain\user] /password=[password] /unattended WindowsService1.exe
Note: the switches must precede the service path, otherwise be ignored.
This feature of InstallUtil seems very little documented. In fact, I’ve noticed that by preceding a ‘/?’ before the service path, more information uncovered than found on MSDN.The command:
installutil /? WindowsService1.exe
The output – the interesting bit marked in yellow below: Microsoft (R) .NET Framework Installation utility Version 4.0.30319.1
Copyright (c) Microsoft Corporation. All rights reserved.
Usage: InstallUtil [/u | /uninstall] [option [...]] assembly [[option [...]] assembly] [...]]
InstallUtil executes the installers in each given assembly.
If the /u or /uninstall switch is specified, it uninstalls
the assemblies, otherwise it installs them. Unlike other
options, /u applies to all assemblies, regardless of where it
appears on the command line.
Installation is done in a transactioned way: If one of the
assemblies fails to install, the installations of all other
assemblies are rolled back. Uninstall is not transactioned.
Options take the form /switch=[value]. Any option that occurs
before the name of an assembly will apply to that assembly's
installation. Options are cumulative but overridable – options
specified for one assembly will apply to the next as well unless
the option is specified with a new value. The default for all
options is empty or false unless otherwise specified.
Options for installing any assembly:
The assembly parameter will be interpreted as an assembly name (Name,
Locale, PublicKeyToken, Version). The default is to interpret the
assembly parameter as the filename of the assembly on disk.
File to write progress to. If empty, do not write log. Default
If false, suppresses output to the console.
If an exception occurs at any point during installation, the call
stack will be printed to the log.
Directory in which the .InstallState file will be stored. Default
is the directory of the assembly.
Options for installing a Service Application:
Sets the user account to run the service under. You must also
specify the /password= option.
Sets the password for the account to run the service under.
The /username and /password options will be used only if the vendor of
the service designated it as requiring a user account. If a service was
so designated, and you do not use the /username and /password options,
you will be prompted at install time for the account.
Unattended install. Will not prompt for username or password.
Individual installers used within an assembly may recognize other
options. To learn about these options, run InstallUtil with the paths
of the assemblies on the command line along with the /? or /help option.
So by using these options we can pass username and password for unattended installation. This is great for taking control of the service installation flow from the MSI to the code.
Next step is how to roll out this unattended feature within an MSI installer.
During the install phase InstallUtil calls this 'Set Service Login' dialog:
This is perfectly normal, since no username\password have been provided. Provide valid credentials and the service installed.