使用c#或cmd中的提升权限和管理员用户凭据卸载Msiexec

时间:2016-05-26 10:39:44

标签: c# cmd wix msiexec

我们有一个配置应用程序,其中包含由网络管理员管理的软件的服务器和客户端设置详细信息。在这个应用程序中,我们可以保存管理员用户凭据(加密)以用于我们的主要软件安装。

在我们的自动升级代码中遇到的问题是,传递给运行msiexec命令的管理员用户凭据是该帐户没有管理权限,即使用户在目标PC上被标记为本地管理员。使用域管理员的用户凭据遇到了同样的问题。使用msi GUI进行手动卸载,在以特定管理员用户身份登录时可以正常运行。代码成功卸载软件的唯一时间,就是我让域管理员暂时将主管理员用户凭据保存在配置应用程序中(当然是出于测试目的),这不是为了能够保存管理员配置应用程序中的凭据。

以下是从msiexec日志中提取的详细信息,详细说明了遇到的错误:

MSI(s)(80:3C)[11:01:00:674]:机器策略值'AlwaysInstallElevated'为0
MSI(s)(80:3C)[11:01:00:674]:用户政策值'AlwaysInstallElevated'为0
MSI(s)(80:3C)[11:01:00:674]:MSI_LUA:静音安装禁用高程提示

MSI(s)(80:3C)[11:01:00:674]:注意:1:1730 操作开始11:01:00:InstallInitialize。
MSI(s)(80:3C)[11:01:00:674]:产品:客户端软件 - 错误1730.您必须是管理员才能删除此应用程序。要删除此应用程序,您可以以管理员身份登录,或与技术支持小组联系以获取帮助。

现在代码部分: 这是在调用ExecuteInstaller方法之前的卸载设置

                //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);

现在运行该过程:

    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);
            }
        }
    }

即使使用提升的权限,所执行的步骤也可以在cmd提示符内重现。例如:

C:> runas / user:domain \ user“msiexec.exe / quiet / uninstall {936DDA62-6793-4713-999 7-E249CD61D3CB} / l * v \“C:\ msiClientInstallLog.log \”“

使用目标PC上的管理员的域用户运行,不会发生任何事情。只有使用主域\管理员凭据才能成功完成

我们尝试更改导致成功卸载的其他设置是我们更改注册表设置时: HKLM:\ Software \ Microsoft \ Windows \ CurrentVersion \ Policies \ System \ EnableLUA为0.但重点不是禁用UAC,而是使用正确的通道绕过UAC。虽然指定主网络管理员密码不属于该策略的一部分。具有此类权限的管理员帐户就足够了。

必须有GPO设置,允许为指定的管理员帐户凭据进行静默安装。

是否可以以某种方式调用UAC提升提示?

或者将数字签名我们的msi工作?

有没有人对我有任何提示,链接或其他有价值的建议? 我还没有在网上找到任何有价值的东西......

2 个答案:

答案 0 :(得分:0)

虽然这可能不是解决我问题的完美解决方案(因此我不会将其标记为答案):迄今为止我从试验和错误中找到的一个解决方案是从cmd执行以下卸载命令:

C:> runas / user:domain \ user" msiexec.exe / qr / uninstall {936DDA62-6793-4713-999 7-E249CD61D3CB} / l * v \" C:\ msiClientInstallLog .log \""
(输入用户密码并在提示时按Enter键)
(注意从&#34变化;安静"到" qr&# 34;从我原来的问题)

除此之外,我还必须确保UAC设置(在控制面板>用户帐户>更改用户帐户控制设置中找到)设置为至少可用四个中的第二个最低选项;即仅当应用程序尝试更改我的计算机时才通知我(不要使我的桌面变暗)。 以前我的UAC被设置为Never notify,因为无论如何谁都希望看到这些讨厌的弹出窗口。

设置此选项将提示您使用UAC提示允许或拒绝继续权限。如果您选择继续,则最终会升级安装程序,详细日志会显示以下详细信息:

MSI(c)(D4:58)[13:05:35:265]:MSI_LUA:将AdminUser属性设置为1,因为这是客户端或用户已经允许提升 MSI(c)(D4:58)[13:05:35:265]:属性更改:添加AdminUser属性。它的价值是' 1' MSI(c)(D4:58)[13:05:35:265]:MSI_LUA:将MsiRunningElevated属性设置为1,因为安装已经提升了。

随后成功卸载该软件。

我还在寻找/研究一个更好,更自动化的选项,我可以在我的C#代码中执行该选项。
请继续帮助我找到更好的解决方案。

答案 1 :(得分:0)

不确定为什么我之前没有尝试过这个解决方案:

将msiexec.exe选项/被动与/ quiet参数一起使用。 这将在卸载和安装过程中显示卸载/安装进度条,如果已启用,则会提示您UAC。

所以从本质上说,我的解决方案如下:
1.与我之前的回答相同,我需要将UAC级别从无提升到仅当应用程序尝试对我的计算机进行更改时通知我(不要使我的桌面变暗)
2.更改以下c#代码以包含/被动参数

string uninstallCommand = String.Format("/quiet /passive /uninstall {0}", productCode);

您仍然需要记住以管理员身份运行应用程序以使日志记录正常运行。然而,这是提示UAC权限,它将安装程序权限提升到管理员级别并继续成功卸载软件。