views:

133

answers:

1

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

+3  A: 

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 thread for the manifest you need to display the UAC elevation prompt.

Hans Passant
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?
abatishchev
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.
abatishchev
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.
Hans Passant
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?
abatishchev