我正在尝试使用 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 上进行的。我在提升为管理员权限的 VS2008 调试器中运行该进程。
我也试过设置
startInfo.Verb = "runas";
但是好像没有解决问题
您可以通过将 startInfo 对象的 Verb 属性设置为“runas”来指示新进程应该以提升的权限启动,如下所示:
startInfo.Verb = "runas";
这将导致 Windows 的行为就好像进程是从资源管理器中使用“以管理员身份运行”菜单命令启动的一样。
这确实意味着 UAC 提示将出现并且需要用户确认:如果这是不可取的(例如因为它会在一个漫长的过程中发生),您将需要运行整个主机进程通过 Create and Embed an Application Manifest (UAC) 提升权限以要求“highestAvailable”执行级别:这将导致 UAC 提示在您的应用程序启动后立即出现,并导致所有子进程以提升的权限运行无需额外提示。
编辑:我看到您刚刚编辑了您的问题以说明“runas”对您不起作用。这真的很奇怪,因为它应该(并且在几个生产应用程序中对我来说确实如此)。不过,通过嵌入清单要求父进程以提升的权限运行应该绝对有效。
此代码将以上所有内容放在一起,并使用管理员权限重新启动当前的 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 没有运行,我的主窗口就会爆炸,在某些竞争条件下它会这样做。
根据文章 Chris Corio:教您的应用程序使用 Windows Vista 用户帐户控制很好地运行,MSDN 杂志,2007 年 1 月,只有
ShellExecute
检查嵌入式清单并在需要时提示用户提升,而CreateProcess
而其他 API 则没有。希望对您有所帮助。
另请参阅:与 .chm 相同的文章.
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")]
这将在没有 UAC 的情况下完成 - 无需启动新进程。对于我的情况,如果运行用户是管理员组的成员。
我知道这是一篇很老的帖子,但我只是想分享我的解决方案:
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。
你应该使用模拟来提升状态。
WindowsIdentity identity = new WindowsIdentity(accessToken);
WindowsImpersonationContext context = identity.Impersonate();
完成后不要忘记撤消模拟上下文。
有另一种方法可以启动需要提升的进程,而不必使用窗口
Task Scheduler
在父进程中进行提升。基本上你创建一个任务并在Run with highest privileges
选项卡中检查General
。可以使用 Windows API 或 nuget 库以编程方式运行该任务。甚至可以动态创建这样的任务,运行它并再次删除它。
使用 TaskScheduler 库在代码中创建任务如下所示:
TaskDefinition td = ts.NewTask();
td.Principal.RunLevel = TaskRunLevel.Highest; // <-- for elevation
// Set trigger and action and other properties...
ts.RootFolder.RegisterTaskDefinition("Test", td);