在允许基于用户的操作的同时提升MSI安装

时间:2013-08-29 17:56:47

标签: c# process windows-installer user-profile elevation

是的,有许多与安装MSI软件包时提升权限相关的文章。我对这个问题有一个转折,我找不到一个好的答案。如果我以用户身份登录并运行MSI提升代码(下方),软件包安装但当前用户操作将对我提升安装程序的用户执行。
例如,如果MSI将文件添加到CURRENT USER的桌面。提升的结果(作为“Joe Admin”运行)是将文件放在Joe Admin的桌面上 - 而不是当前登录的用户(“Sally User”)。我拥有Elevates as Joe的软件,但将文件放在Sally的桌面上,就像安装它一样。 - 我想写自己的。这是在Windows 7计算机上,UAC已关闭。

这是非工作代码。 (Sally已登录,Elevate as Joe -File转到Joe的桌面)(LoadUserProfile属性试图解决此问题 - 无法正常工作)。

    Process watchThis = ImpersonateInstaller(@"c:\temp\Test.msi", "SuperJoePassword");
    watchThis.WaitForExit();       

    private static Process ImpersonateInstaller(string msiPath, string Password)
    {
        Domain d = Domain.GetCurrentDomain();
        Process process = new Process();
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.LoadUserProfile = true;
        process.StartInfo.FileName = @"C:\Windows\System32\msiexec.exe";
        process.StartInfo.Arguments = string.Format(@"/i {0} REBOOT=ReallySuppress /qb-", msiPath);
        process.StartInfo.WorkingDirectory = Environment.GetEnvironmentVariable("WINDIR");
        process.StartInfo.UserName = "JoeAdmin";
        process.StartInfo.Password = new SecureString();
        process.StartInfo.Domain = d.ToString();
        foreach (char c in Password.ToCharArray())
        {
            process.StartInfo.Password.AppendChar(c);
        }
        process.Start();
        return process;
    }

2 个答案:

答案 0 :(得分:1)

从提升的流程调用msiexec /jm foo.msi执行广告。这祝福了包裹。从标准用户进程调用msiexec /I foo.msi REBOOT=R /qb,这将以用户身份开始安装,但根据需要无缝升级。没有模拟的标准操作和自定义操作将作为SYSTEM运行,带Impeornation的自定义操作将作为没有设计权限的用户运行。

答案 1 :(得分:0)

在Christopher Painter的帮助下,这似乎就是答案(感谢CHRISTOPHER !!!) 我以前读过“广告”这个词,并且总是认为它与“在GPO中发布”有关,所以我从来没有完成过。好像我错了。如果其他人遇到这个问题,这就是诀窍。

首先,通过提升权限来宣传“祝福”msi以便最终用户安装。在我看来,管理员说,确保这个msi对于Sally最终用户安装是安全的:

msiexec.exe /jm install.msi

然后,以最终用户身份安装,就好像他们是管理员一样:

msiexec.exe /i install.msi /your /typcial /installOption /switches /here

我的代码(肯定会更好):

        Process advertise = advertiseMSI(@"c:\temp\test.msi", "JoeWhoHasAdminRights", "Joe'sSuperPassword");
        advertise.WaitForExit();
        Process install = installMSI(@"c:\temp\test.msi");
        install.WaitForExit();


    private static Process advertiseMSI(string msiPath, string userName, string Password)
    {
        Domain domain = Domain.GetCurrentDomain();
        Process process = new Process();
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.FileName = @"C:\Windows\System32\msiexec.exe";
        process.StartInfo.Arguments = string.Format(@"/jm {0}", msiPath);
        process.StartInfo.WorkingDirectory = Environment.GetEnvironmentVariable("WINDIR");
        process.StartInfo.UserName = userName;
        process.StartInfo.Password = new SecureString();
        foreach (char c in Password.ToCharArray())
        {
            process.StartInfo.Password.AppendChar(c);
        }
        process.StartInfo.Domain = domain.ToString();            
        process.Start();
        return process;
    }

    private static Process installMSI(string msiPath)
    {
        Process process = new Process();
        process.StartInfo.FileName = @"C:\Windows\System32\msiexec.exe";
        process.StartInfo.Arguments = string.Format(@"/i {0} REBOOT=ReallySuppress /qb-", msiPath);
        process.StartInfo.WorkingDirectory = Environment.GetEnvironmentVariable("WINDIR");
        process.Start();
        return process;
    }