Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run new process as admin and read standard output

Tags:

c#

I want to allow users to run a command line utility as administrator from within my non-admin program and for my program to get the output. The utility is third-party but is distributed with my programme.

I can redirect the output of a program and I can run a program as administrator but I can't do both at the same time.

The only thing that I can get to work at the moment is using cmd.exe to redirect the output to a file, e.g.:

using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Reflection;

string appDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string utilityPath = Path.Combine(appDirectory, "tools", "utility.exe");
string tempFile = Path.GetTempFileName();

Process p = new Process();
// hide the command window
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.FileName = "cmd.exe";
// run the tool, redirect the output to the temp file and then close.
p.StartInfo.Arguments = " /C \"\"" + utilityPath + "\" > \"" + tempFile + "\"\"";
p.StartInfo.Verb = "runas"; // run as administrator
p.Start();
p.WaitForExit();

// get the output, delete the file and show the output to the user
string output = File.ReadAllText(tempFile);
File.Delete(tempFile);
MessageBox.Show(output);

This has two problems: 1) it uses a temporary file and 2) the UAC is for cmd.exe rather then utility.exe. There must surely be a better way to do this?

like image 470
ChrisD Avatar asked Apr 01 '13 15:04

ChrisD


1 Answers

Instead of executing through a new cmd, try executing the utility directly. And instead of redirecting to a file, redirect the standard output to read it from your program. In order to run as admin, you'll need to use the admin username and password (taken from here). You'll need to set your method as unsafe:

unsafe public static void Main(string[] args){
    Process p = new Process();
    p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    // set admin user and password
    p.StartInfo.UserName = "adminusername";
    char[] chArray = "adminpassword".ToCharArray();
    System.Security.SecureString str;
    fixed (char* chRef = chArray) {
        str = new System.Security.SecureString(chRef, chArray.Length);
    }
    p.StartInfo.Password = str;
    // run and redirect as usual
    p.StartInfo.FileName = utilityPath;
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;
    p.Start();
    string output = p.StandardOutput.ReadToEnd();
    Console.WriteLine(output);
    p.WaitForExit();
}
like image 157
Julián Urbano Avatar answered Oct 11 '22 19:10

Julián Urbano