We have a configuration application which contains the server and client setup details of our software which is managed by network administrators. In this app we can save admin user credentials (which are encrypted) to use for our main software installations.
The problem encountered during our auto upgrade code is that the administrator user credentials passed to run the msiexec command is that the account does not have administrative permissions even though the user is marked as local administrator on the target pc. The same problem was encountered using the domain administrators' user credentials. Manual un-installations using the msi GUI go through just fine when logged on as that particular admin user. The only time the code goes through successfully uninstalling the software, is if I get the domain admin to temporarily save the main administrator user credentials in the config application (for testing purposes of course), which is not the intention of being able to save admin credentials in the config application.
The following are the details extracted from the msiexec log detailing the error encountered:
MSI (s) (80:3C) [11:01:00:674]: Machine policy value 'AlwaysInstallElevated' is 0
MSI (s) (80:3C) [11:01:00:674]: User policy value 'AlwaysInstallElevated' is 0
MSI (s) (80:3C) [11:01:00:674]: MSI_LUA: Elevation prompt disabled for silent installs
MSI (s) (80:3C) [11:01:00:674]: Note: 1: 1730
Action start 11:01:00: InstallInitialize.
MSI (s) (80:3C) [11:01:00:674]: Product: Client Software -- Error 1730. You must be an Administrator to remove this application. To remove this application, you can log on as an Administrator, or contact your technical support group for assistance.
Now for the code part: This is the uninstall setup prior to calling the ExecuteInstaller method
//uninstall...
if (log.IsInfoEnabled)
{
log.Info("Autoupdate: uninstalling current client.");
}
string uninstallCommand = String.Format("/quiet /uninstall {0}", productCode);
if (log.IsDebugEnabled)
{
log.Debug("Autoupdate: Adding verbose msi logging to \"msiClientUnInstallLog.log\"");
uninstallCommand += " /l*v \"msiClientUnInstallLog.log\"";
}
ExecuteInstaller(uninstallCommand);
Now to run the process:
private void ExecuteInstaller(string command)
{
if (log.IsDebugEnabled)
{
log.Debug("Autoupdate: executing command: " + command);
}
ProcessStartInfo startInfo = new ProcessStartInfo("msiexec.exe", command);
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
if (log.IsDebugEnabled)
{
log.Debug("Autoupdate: reinstall using elevated priviledges.");
}
startInfo.Verb = "runas";
if (!String.IsNullOrEmpty(BaseSettings.Environment.Server.ClientInstallerUserName))
{
if (log.IsDebugEnabled)
{
log.DebugFormat("Autoupdate: an installer username was specified: {0}, domain: {1}. Installing using supplied credentials...", BaseSettings.Environment.Server.ClientInstallerUserName, BaseSettings.Environment.Server.ClientInstallerDomain);
}
startInfo.Domain = BaseSettings.Environment.Server.ClientInstallerDomain;
startInfo.UserName = BaseSettings.Environment.Server.ClientInstallerUserName;
/*Hidden: Decrypt the encrypted admin password and save secure string to new parameter.*/
System.Security.SecureString installPassword = new System.Security.SecureString();
/*Hidden: Decrypt the encrypted admin password and save secure string to new parameter.*/
startInfo.Password = installPassword;
startInfo.UseShellExecute = false;
}
Process process = Process.Start(startInfo);
if (process != null)
{
process.WaitForExit();
if (log.IsDebugEnabled)
{
log.DebugFormat("Autoupdate: command finished with exit code: {0}", process.ExitCode);
}
if (process.ExitCode != 0)
{
string errorMessage = String.Format("Autoupdate: The upgrade of this Client failed. Please ask an administrator to upgrade it for you.");
log.Error(errorMessage);
throw new Exception(errorMessage);
}
}
}
The steps undertaken are reproducible from within cmd prompt even with elevated privileges. For example:
C:>runas /user:domain\user "msiexec.exe /quiet /uninstall {936DDA62-6793-4713-999 7-E249CD61D3CB} /l*v \"C:\msiClientInstallLog.log\""
Running with a domain user which is an administrator on the target pc, results in nothing happening. Only if you use the main domain\administrator credentials does this go through successfully
Other settings we attempted to change which result in successful un-installations is when we change the registry setting: HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA to 0. However the point is not to disable the UAC but rather to use the correct channels to bypass the UAC. Specifying the main network admin password though does not fall part of that strategy. An administrator account with such privileges should suffice.
There must be a GPO setting which will allow silent installations for the specified admin account credentials.
Is it possible to call the UAC elevation prompt somehow?
Alternatively would digitally signing our msi's work?
Does anyone have any hints, links or other valuable advice for me to try? I haven't found anything valuable on the net yet...