UseShellExecute=false 时无法提升权限

发布于 2024-09-16 14:19:33 字数 1181 浏览 6 评论 0 原文

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

我执行下一步:

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

I want to start a child process (indeed the same, console app) with elevated privileges but with hidden window.

I do next:

var info = new ProcessStartInfo(Assembly.GetEntryAssembly().Location)
{
    UseShellExecute = true, // !
    Verb = "runas", 
};

var process = new Process
{
    StartInfo = info
};

process.Start();

and this works:

var identity = new WindowsPrincipal(WindowsIdentity.GetCurrent());
identity.IsInRole(WindowsBuiltInRole.Administrator); // returns true

But UseShellExecute = true creates a new window and I also I can't redirect output.

So when I do next:

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();

This doesn't elevate privileges and code above returns false. Why??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱给你人给你 2024-09-23 14:19:33

ProcessStartInfo.Verb 仅当进程由 ShellExecuteEx() 启动时才有效。这需要 UseShellExecute = true。仅当进程由 CreateProcess() 启动时,重定向 I/O 和隐藏窗口才有效。这需要 UseShellExecute = false。

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

检查此问答< /a> 对于清单,您需要显示 UAC 提升提示。

ProcessStartInfo.Verb will only have an effect if the process is started by ShellExecuteEx(). Which requires UseShellExecute = true. Redirecting I/O and hiding the window can only work if the process is started by CreateProcess(). Which requires UseShellExecute = false.

Well, that's why it doesn't work. Not sure if forbidding to start a hidden process that bypasses UAC was intentional. Probably. Very probably.

Check this Q+A for the manifest you need to display the UAC elevation prompt.

要走就滚别墨迹 2024-09-23 14:19:33

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

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);

In my case, it was ok to get the outputs once the elevated child process is done. Here's the solution I came up. It uses a temporary file :

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);
热风软妹 2024-09-23 14:19:33

检查此答案

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

Check this answer.

This seems to provide a workaround. But I recommend to try other methods like Named Pipes when you have access to source code of the child process.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文