Elevating privileges doesn't work with UseShellExecute=false
Asked Answered
R

3

25

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??

Rahel answered 29/8, 2010 at 19:32 Comment(2)
BTW, you can write DataReceivedEventHandler actionWrite = ... and process.ErrorDataReceived += actionWrite.Titicaca
Can you test using UseShellExecute = true, Verb = "runas", and ErrorDataReceived events as @Titicaca comment ?Carping
H
24

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.

Hoover answered 29/8, 2010 at 19:58 Comment(5)
Thank you very much for WinAPI behind-the-scene description. How do you think is it possible to get elevated privileges on demand for a process with hidden window? Or this is mutually exclusive things?Rahel
And is it possible to switch on/off using manifest? I.e. when I start my app first time (manually) - don't use a manifest, when second (programmatically) - force to use.Rahel
Starting a process with elevated privileges without the user knowing about it is not possible. You need a separate .exe so that it has its own manifest. Basically you only need the Main() method.Hoover
I don't want to hide process launch from user, I still need UAC confirm from him, I just want to hide started process window. I think this isn't possible too, right?Rahel
Hmm... this is rather frustrating.Elwandaelwee
C
14

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);
Cyclic answered 17/3, 2016 at 11:27 Comment(2)
this actually appears to be working for me. convoluted details (windows 10, F#) - gist at gist.github.com/ImaginaryDevelopment/…Phrase
The accepted answer is an explanation, this is a solution.. +1Replay
T
0

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.

Tanker answered 15/10, 2013 at 13:7 Comment(2)
I haven't tested the UAC article approach, though it contains a sample by itself. But if you mean a sample for Named Pipes, you can easily find many of them (like this or this) with a little search. The point is that like I/O redirection, you can use textual streams with Named Pipes too, to send and receive data (even if the two processes reside on different machines). Of course you have to deal with some nuances to get a fully working application.Tanker
@Rahel IMHO, better using Trace to File, not redirect output, verb = runas. Named Pipes is much more complex and complex to debugging easy.Carping

© 2022 - 2024 — McMap. All rights reserved.