通过编程提升进程特权?

我正在尝试使用 InstallUtil.exe 安装一个服务,但是通过 Process.Start调用了该服务:

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

其中 m_strInstallUtil是“ InstallUtil.exe”的完全限定路径和 exe,而 strExePath是我的服务的完全限定路径/名称。

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

这都是在 WindowsVista 上运行的。我在 VS2008调试器中运行进程,升级为管理员特权。

我也尝试设置 startInfo.Verb = "runas";,但似乎没有解决这个问题。

230125 次浏览

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

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

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

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

startInfo.Verb = "runas";

这将导致 Windows 的行为,就好像进程已经从资源管理器启动,并使用“作为管理员运行”菜单命令。

这确实意味着 UAC 提示将会出现,并且需要得到用户的确认: 如果这是不可取的(例如,因为它会发生在一个漫长的进程的中间) ,你将需要运行你的整个主机进程与提升的权限 创建和嵌入应用程序清单(UAC)要求’最高可用’的执行级别: 这将导致 UAC 提示一旦你的应用程序启动就会出现,并导致所有子进程在没有额外提示的情况下以提升的权限运行。

编辑: 我看到你刚刚编辑了你的问题,声明“ runas”不适合你。这真的很奇怪,因为它应该(而且在我的几个生产应用程序中也是如此)。但是,通过嵌入清单要求父进程使用提升的权限运行肯定是可行的。

根据 Chris Corio: Teach Your Apps To Play Nice With Windows Vista User Account Control,MSDN Magazine,2007年1月 文章,只有 ShellExecute检查嵌入的清单并在需要时提示用户提升,而 CreateProcess和其他 API 不检查。希望能有帮助。

参见: 与.chm 同一篇文章

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

这将做到没有 UAC-没有必要开始一个新的过程。如果正在运行的用户是 Admin 组的成员,就像我的情况一样。

这段代码将以上所有内容组合在一起,并使用 admin pris 重新启动当前的 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)

更新: 应用程序清单方式是首选的:

右键单击项目在可视化工作室,添加,新的应用程序清单文件,更改文件,使您有必要的管理员设置,如上所示。

原始方法的一个问题是: 如果将重启代码放在 app.xaml.cs OnStartup 中,即使调用了 Shutdown,它仍然可以短暂地启动主窗口。如果 app.xaml.cs init 没有运行,并且在某些比赛条件下它会这样做,那么我的主窗口就会崩溃。

我知道这是一个很老的帖子,但我只是想分享我的解决方案:

System.Diagnostics.ProcessStartInfo StartInfo = new System.Diagnostics.ProcessStartInfo
{
UseShellExecute = true, //<- for elevation
Verb = "runas",  //<- for elevation
WorkingDirectory = Environment.CurrentDirectory,
FileName = "EDHM_UI_Patcher.exe",
Arguments = @"\D -FF"
};
System.Diagnostics.Process p = System.Diagnostics.Process.Start(StartInfo);

注意: 如果 VisualStudio 已经在运行 Elevated,那么 UAC 对话框将不会显示,要测试它,请从 bin 文件夹运行 exe。