Search code examples
c#.netprocesselevated-privilegesadmin-rights

Start process with higher privileges and read its output


We need to start a process with required admin privileges (defined in its app.manifest) in a normal process and read its output. The way I see it, in order to start a process with higher right, we need to set UseShellExecute = true. But that prevents us from receiving the standard output.
Here is my code snippet, but it needs the current process to have admin privileges too (that we cannot afford since it's a huge application and this is the only section that needs elevation):

if (bAdmin)
{
    Process p = new Process
    {
        StartInfo =
        {
            Arguments = "-GetRestorePoints",
            FileName = Environment.CurrentDirectory + @"\Hamekare.AdminSettings.exe",
            CreateNoWindow = true,
            WindowStyle = ProcessWindowStyle.Hidden,
            RedirectStandardOutput = true,
            UseShellExecute = false
        }
    };

    p.OutputDataReceived += p_OutputDataReceived;
    p.Start();
    p.BeginOutputReadLine();
}

Solution

  • I ended up using Named Pipes.
    Server:

    PipeSecurity ps = new PipeSecurity();
    PipeAccessRule psRule = new PipeAccessRule(@"Everyone", PipeAccessRights.ReadWrite, System.Security.AccessControl.AccessControlType.Allow);
    ps.AddAccessRule(psRule);
    var server = new NamedPipeServerStream("HKBackUpRestorePipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 1, 1, ps);
    server.WaitForConnection();
    
    StreamWriter writer = new StreamWriter(server);
    writer.WriteLine ...
    writer.Flush();
    

    Client:

    var client = new NamedPipeClientStream("HKBackUpRestorePipe");
    client.Connect();
    StreamReader reader = new StreamReader(client);
    StreamWriter writer = new StreamWriter(client);
    
    string line;
    
    while ((line = reader.ReadLine()) != "\t\t<<Finished!>>")
        ...