以管理员身份运行的进程如何以用户身份启动进程

8
我希望能够从以管理员身份运行的程序开始另一个以用户身份运行的程序。
问题在于第二个程序需要使用Outlook,如果程序以管理员身份运行,则不可能。主要程序需要以管理员身份运行。
我已经想出了以下两个解决方案:
Process.Start("cmd.exe", @"/C runas.exe /savecred /user:" + Environment.UserDomainName + "\\" + Environment.UserName + " " + "\"SomeProgram.exe" + "\"");

或者

Process.Start("explorer.exe", "SomeProgram.exe");

但是我对这两种解决方案都有问题。 第一种要求用户输入密码(只有在Windows重启后的第一次)。 第二种可能在未来不起作用,因为据我所知,它被视为一个错误,可能会在未来的更新中修复。 所以,我想知道是否还有其他解决方案,用户不需要输入密码? 这对我似乎有效:
Process.Start("cmd.exe", @"/C runas.exe /TrustLevel:0x20000  " + "\"SomeProgram.exe" + "\"");

1
Raymond Chen在如何从我的提升进程启动非提升进程,反之亦然?中描述得非常好(还涵盖了各种细节,例如当提升使用不同的帐户凭据与会话其余部分使用的凭据时)。 - Damien_The_Unbeliever
但这不是使用exploer.exe完成工作的另一种方式吗? 无论如何,我找到了另一个解决方案,我已经将其添加到原始帖子中。 - FKorni
你的解决方案是否正确处理了从Alice的管理员帐户降级到Bob的用户帐户的情况(使用Raymonds链接中的示例)? - Damien_The_Unbeliever
runas /trustlevel 这个东西会让进程处于奇怪的状态,最好还是避免使用。请参考 https://dev59.com/OYzda4cB1Zd3GeqPjTbA。 - Harry Johnston
一个解决方法是编写一个以用户身份运行的父程序,该程序启动管理员进程,然后再启动用户进程。但 Raymond 的解决方案可能更可靠;是的,它使用了资源管理器,但是这样做是“合法的”。 - Harry Johnston
我目前无法在Win 8机器上测试它,所以我不确定我的解决方案在那里与Outlook的配合情况如何。在Win 7上似乎做得很好。如果在Win 8下无法工作,我需要进行调整。 - FKorni
2个回答

1

Process类有一个StartInfo属性,它是一个ProcessStartInfo类的实例。该类公开了UserNameDomainPassword成员,以指定您要运行进程的用户。

Process myProcess = new Process();
myProcess.StartInfo.FileName = fileName;
myProcess.StartInfo.UserName = userName;
myProcess.StartInfo.Domain = domain;
myProcess.StartInfo.Password = password;
myProcess.Start();

1
这意味着我需要知道用户密码,但事实并非如此。该程序由许多不同的用户使用,因此这对我来说不是一个选项。 - FKorni
@FKorni 我认为你不能在不知道凭据的情况下冒充另一个用户。 - Matteo Umili
主程序通过清单请求管理员权限,但第二个程序应该在当前会话的普通用户下运行。 - FKorni
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Matteo Umili
如果运行该进程的用户是已登录的用户,则可以按照Damien_The_Unbeliever提供的链接进行操作。@FKorni - Matteo Umili
我想出了另一种解决方案,似乎对我有效。我已经编辑了我的第一篇帖子。 - FKorni

0

我曾经遇到同样的问题,无法获取当前登录用户。注意:查询WMI不是解决方案,因为在那时可能有多个用户登录。所以我的解决方案是相反的。以当前用户身份启动我的应用程序,如果当前用户不是管理员,则请求以管理员身份运行。

if (IsAdministrator())
{
    // run whatever you want as elevated user
}
else
{
    //launch the same app as admin
    ExecuteAsAdmin(PATHH_TO_THE_SAME_APP.EXE);
    //execute whatever you want as current user.
}



public static void ExecuteAsAdmin(string fileName)
{
    Process proc = new Process();
    proc.StartInfo.FileName = fileName;
    proc.StartInfo.UseShellExecute = true;
    proc.StartInfo.Verb = "runas";

    proc.Start();
    proc.WaitForExit();
}

public static bool IsAdministrator()
{
    var identity = WindowsIdentity.GetCurrent();
    var principal = new WindowsPrincipal(identity);
    return principal.IsInRole(WindowsBuiltInRole.Administrator);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接