21

我想启动一个具有提升权限但具有隐藏窗口的子进程(实际上是相同的控制台应用程序)。

我接下来做:

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。为什么??

4

3 回答 3

21

ProcessStartInfo.Verb 只有在进程由 ShellExecuteEx() 启动时才会生效。这需要 UseShellExecute = true。重定向 I/O 和隐藏窗口只有在进程由 CreateProcess() 启动时才能起作用。这需要 UseShellExecute = false。

好吧,这就是为什么它不起作用。不确定禁止启动绕过 UAC 的隐藏进程是否是故意的。大概。 可能。

检查此 Q+A以获得显示 UAC 提升提示所需的清单。

于 2010-08-29T19:58:59.513 回答
9

就我而言,一旦提升的子进程完成,就可以获取输出。这是我提出的解决方案。它使用一个临时文件:

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);
于 2016-03-17T11:27:23.103 回答
0

检查这个答案

这似乎提供了一种解决方法。但是当您可以访问子进程的源代码时,我建议您尝试其他方法,例如命名管道。

于 2013-10-15T13:07:54.840 回答