我想启动一个子进程(实际上是相同的控制台应用程序),具有提升的权限但隐藏窗口。
我接下来会这样做:
var info = new ProcessStartInfo(Assembly.GetEntryAssembly().Location)
{
UseShellExecute = true, // !
Verb = "runas",
};
var process = new Process
{
StartInfo = info
};
process.Start();
这有效:
var identity = new WindowsPrincipal(WindowsIdentity.GetCurrent());
identity.IsInRole(WindowsBuiltInRole.Administrator); // returns true
但UseShellExecute = true
创建了一个新窗口,我也无法重定向输出。
所以当我接下来的时候:
var info = new ProcessStartInfo(Assembly.GetEntryAssembly().Location)
{
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false, // !
Verb = "runas"
};
var process = new Process
{
EnableRaisingEvents = true,
StartInfo = info
};
DataReceivedEventHandler actionWrite = (sender, e) =>
{
Console.WriteLine(e.Data);
};
process.ErrorDataReceived += actionWrite;
process.OutputDataReceived += actionWrite;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
这不会提升权限,上面的代码返回false。为什么?
答案 0 :(得分:17)
ProcessSartInfo.Verb只有在ShellExecuteEx()启动进程时才会生效。这需要UseShellExecute = true。重定向I / O并隐藏窗口只能在CreateProcess()启动进程时才能工作。这需要UseShellExecute = false。
嗯,这就是为什么它不起作用。不确定是否禁止启动绕过UAC的隐藏进程是故意的。大概。 非常可能。
检查this Q+A以查看显示UAC提升提示所需的清单。
答案 1 :(得分:6)
在我的情况下,一旦提升的子进程完成,就可以获得输出。这是我提出的解决方案。它使用临时文件:
var output = Path.GetTempFileName();
var process = Process.Start(new ProcessStartInfo
{
FileName = "cmd",
Arguments = "/c echo I'm an admin > " + output, // redirect to temp file
Verb = "runas", // UAC prompt
UseShellExecute = true,
});
process.WaitForExit();
string res = File.ReadAllText(output);
// do something with the output
File.Delete(output);
答案 2 :(得分:0)
检查this answer。
这似乎提供了一种解决方法。但是,当您有权访问子进程的源代码时,我建议尝试其他方法,例如Named Pipes。