0

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

这是非工作代码。(Sally 已登录,在 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;
    }
4

2 回答 2

1

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

于 2013-08-29T18:47:04.807 回答
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;
    }
于 2013-08-30T14:37:11.957 回答