Hi all,
This is something that I have been toying with for about a week now. What
I want to achieve is Install a Service with Customised parameters (using
InstallUtil.exe ) for User Name. Example (C#);
[RunInstaller(tr ue)]
public class MyServiceInstal ler : System.Configur ation.Install.I nstaller
{
private System.ServiceP rocess.ServiceP rocessInstaller
serviceProcessI nstaller;
private System.ServiceP rocess.ServiceI nstaller serviceInstalle r;
public MyServiceInstal ler()
{
this.servicePro cessInstaller = new
System.ServiceP rocess.ServiceP rocessInstaller ();
this.serviceIns taller = new System.ServiceP rocess.ServiceI nstaller();
// Null out UserName and password
//POINT1
this.servicePro cessInstaller.P assword = null;
this.servicePro cessInstaller.U sername = null;
// this.servicePro cessInstaller.A ccount =
System.ServiceP rocess.ServiceA ccount.User;
// Service Installer, set ServiceName to same as ServiceName in
ServiceBase derived class
this.serviceIns taller.ServiceN ame = "MyService" ;
// Add Both Installers to Project Installers Collection to be Run
this.Installers .AddRange(new System.Configur ation.Install.I nstaller[] {
this.servicePro cessInstaller,
this.serviceIns taller});
}
//POINT2 Override Install Method to add customised values
public override void Install(System. Collections.IDi ctionary stateSaver)
{
Console.WriteLi ne("Install Start...");
// Check for Custom User
if (this.Context.P arameters.Conta insKey("MyUserN ame") == true)
{
Console.WriteLi ne("******* Using CUSTOMISED values ....");
this.servicePro cessInstaller.A ccount =
System.ServiceP rocess.ServiceA ccount.User;
this.servicePro cessInstaller.P assword =
this.Context.Pa rameters["MyPassword "];
string user = this.Context.Pa rameters["MyUserName "];
string domain = this.Context.Pa rameters["MyDomainNa me"];
// Do we use Principal Name @ Authority or
Authority\Princ ipal ( Domain\User )
string userName = string.Empty;
if (domain.IndexOf (".") -1 && domain.Length 1)
{
userName = string.Concat(u ser, "@", domain);
}
else
{
userName = string.Concat(d omain, "\\", user);
}
// Update the Correct user Name
this.servicePro cessInstaller.U sername = userName;
}
else
{
Console.WriteLi ne("******* Using HARDCODED values ....");
this.servicePro cessInstaller.P assword = "password";
this.servicePro cessInstaller.U sername = "DOMAIN\\Us er";
this.servicePro cessInstaller.A ccount =
System.ServiceP rocess.ServiceA ccount.User;
}
Console.WriteLi ne("******* Username: {0}, Account: {1},
Password: {2}",
this.servicePro cessInstaller.U sername,
this.servicePro cessInstaller.A ccount,
this.servicePro cessInstaller.P assword);
// Call the Base Class to finish Installation
base.Install(st ateSaver);
Console.WriteLi ne("Install End...");
}
}
POINT1 - I have nulled the User Name and Password Fields and left the
Account Type as default in the MyServiceInstal ler Constructor. I could
hard-code the values here, but that defeats the purpose of the exercise.
POINT2 -
a) Running the command "InstallUti l MyService.exe" generates the following
Console Log (minus .NET. Framework Installation ...);
Install Start...
******* Using HARDCODED values ....
******* Username: DOMAIN\User, Account: User, Password: password
Install End...
b) Running the command "InstallUti l /MyUserName=User /MyDomainName=DO MAIN
/MyPassword=pass word MyService.exe" generates; (after Uninstall if above was
run first "InstallUti l /u MyService.exe")
Install Start...
******* Using CUSTOMISED values ....
******* Username: DOMAIN\User, Account: User, Password: password
Then Error Details;
An exception occurred during the Install phase.
System.Componen tModel.Win32Exc eption: The account name is invalid or does
not exist, or the password is invalid for the account name specified
at System.ServiceP rocess.ServiceI nstaller.Instal l(IDictionary stateSaver)
at System.Configur ation.Install.I nstaller.Instal l(IDictionary stateSaver)
at TemplateService .TemplateServic eInstaller.Inst all(IDictionary
stateSaver) in
D:\Projects\Tes t\Services\Temp lateService\Tem plateServiceIns taller.cs:line 124
at System.Configur ation.Install.I nstaller.Instal l(IDictionary stateSaver)
at System.Configur ation.Install.A ssemblyInstalle r.Install(IDict ionary
savedState)
at System.Configur ation.Install.I nstaller.Instal l(IDictionary stateSaver)
at System.Configur ation.Install.T ransactedInstal ler.Install(IDi ctionary
savedState)
The Rollback phase of the installation is beginning.
See the contents of the log file for the
D:\Projects\Tes t\Services\Temp lateService\bin \debug\Template Service.exe
assembly's progress.
The file is located at
D:\Projects\Tes t\Services\Temp lateService\bin \debug\Template Service.Install Log.
The Rollback phase completed successfully.
The transacted install has completed.
The machines that this occurs on are Windows XP Pro and XP Pro 64 (with
their respective x86 and x64 InstallUtil versions) and using .NET Framework
2.0, both connected to a Domain Controller. Changing the User Credentials to
a Local User, Domain Administrator still offers no difference, Hard coded
within Installer works, but using passed custom values to the Install Utility
seems to create some corruption on the install process.
This worked with InstallUtil in .NET v1.1 so am at a loss as to why
Hardcoding works but using the Context.Paramet ers StringDictionar y creates
some kind of Error that InstallUtil cannot handle.
Anyone able to shed some light on this?
TIA Bjorn Ahlstedt