以编程方式提升流程特权?


147

我正在尝试使用InstallUtil.exe安装服务,但通过调用Process.Start。这是代码:

ProcessStartInfo startInfo = new ProcessStartInfo (m_strInstallUtil, strExePath);
System.Diagnostics.Process.Start (startInfo);

其中m_strInstallUtil是“ InstallUtil.exe”的标准路径和exe,并且strExePath是我的服务的标准路径/名称。

从提升的命令提示符下运行命令行语法是可行的;从我的应用程序运行(使用上面的代码)没有。我假设我正在处理一些流程提升问题,那么如何在提升状态下运行流程?我需要看看ShellExecute吗?

这一切都在Windows Vista上。我正在提升为admin特权的VS2008调试器中运行该过程。

我也尝试设置,startInfo.Verb = "runas";但似乎无法解决问题。


我加入后startInfo.UseShellExecute = true;,除了startInfo.Verb = "runas";它的工作对我罚款。
马特

Answers:


172

您可以通过将startInfo对象的Verb属性设置为'runas'来指示应使用提升的权限启动新进程,如下所示:

startInfo.Verb = "runas";

这将导致Windows表现为好像该进程已使用“以管理员身份运行”菜单命令从资源管理器启动。

这确实意味着将出现UAC提示,并且需要用户确认:如果这是不希望的(例如,因为这将在冗长的过程中发生),则需要使用以下命令运行整个主机过程:通过创建和嵌入应用程序清单(UAC)来提升权限,以要求“ highestAvailable”执行级别:这将导致UAC提示在您的应用程序启动后立即出现,并使所有子进程以提升的权限运行而无需其他提示。

编辑:我看到您刚刚编辑了问题,以表明“ runas”不适用于您。确实是很奇怪,因为它应该这样做(并且在几个生产应用程序中对我也是如此)。但是,通过嵌入清单来要求父进程以提升的权限运行是可以的。


9
“ runas”对我也不起作用。可能是它仅在UAC关闭时才有效吗?
Dirk Vollmar,2009年

18
@LukePuplett我要感谢他们。这是缓解Root-kit安装而又不完全隔离用户角色的好方法。
科尔顿2013年

6
@Sparksis,但还有另一种观点。知道如何捍卫自己的操作系统的人,他们知道如何在没有UAC的情况下做到这一点。而不知道防御方式的虚拟用户,每次看到UAC窗口时都单击“是”。同样,没有什么可以阻止恶意黑客病毒编写者利用漏洞绕过它;)所以我同意LukePuplett =)
Jet

24
看来您还必须为此设置startInfo.ShellExecute=true才能工作...而且我也无法使该方法与网络共享上的可执行文件一起使用(在运行之前必须将它们复制到本地temp目录)。 ..
TCC 2013年

7
@Jet对不起,但这是错误的心态。在安装过程中每次显示UAC对话框时,这都是系统故障。有价值的地方是当您看到一个UAC盒子而没有运行任何需要提升的东西时。不管您有多么亲(我们中的任何一个)都认为我们在我们的PC上,您不能神奇地阻止零天/偷渡式下载(例如,最近在诺贝尔奖官方网站上下载)。如果浏览到该站点并看到UAC提示,则说明出了点问题。关闭UAC,您将永远不会知道您刚刚加入了僵尸网络。提前警告的成本是有时需要单击“是”
基本

46

此代码将以上所有内容放在一起,并使用admin privs重新启动当前的wpf应用程序:

if (IsAdministrator() == false)
{
    // Restart program and run as admin
    var exeName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
    ProcessStartInfo startInfo = new ProcessStartInfo(exeName);
    startInfo.Verb = "runas";
    System.Diagnostics.Process.Start(startInfo);
    Application.Current.Shutdown();
    return;
}

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


// To run as admin, alter exe manifest file after building.
// Or create shortcut with "as admin" checked.
// Or ShellExecute(C# Process.Start) can elevate - use verb "runas".
// Or an elevate vbs script can launch programs as admin.
// (does not work: "runas /user:admin" from cmd-line prompts for admin pass)

更新:首选应用清单方式:

在Visual Studio中的项目上单击鼠标右键,添加新的应用程序清单文件,更改文件,以便如上所述设置requireAdministrator。

原始方式存在问题:如果将重新启动代码放在app.xaml.cs OnStartup中,即使调用了Shutdown,它仍然可能短暂地启动主窗口。如果未运行app.xaml.cs init,并且在某些竞争条件下,它会执行此操作,则我的主窗口会爆炸。


参见下面的改进。
JCCyC 2014年

在我的情况下,requireAdministrator无法正常工作。所以我必须按照自己的方式去做。这解决了我的问题!谢谢。但是我必须将单实例应用程序设置为false。
克里斯,2015年

这对我有用。我也将原件传递给string[] args重新生成的过程。
DotNetPadawan


7
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")]

这将在没有UAC的情况下完成-无需启动新流程。就我而言,如果运行用户是Admin组的成员。


3
使用此代码,我得到一个权限错误:“请求安全实体权限失败。” :(
Leonardo

也许是“如果正在运行的用户是管理员成员” *
hB0

1
有趣的是-它可以用于任何方法,而不仅仅是动作方法(我什至在ASPX页面中定义的方法上都尝试过)
Simon_Weaver

1

您应该使用模拟来提升状态。

WindowsIdentity identity = new WindowsIdentity(accessToken);
WindowsImpersonationContext context = identity.Impersonate();

完成后,不要忘记撤消模拟的上下文。


28
您尚未说明如何获取accessToken。启用UAC后,LogonUser将提供用户的受限安全上下文。
2011年

如果您使用的是VSTS,则可以从Web门户的“设置”中获取个人访问令牌。(在用户图片旁边查找设置图标。)MSDocs
Su Llewellyn
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.