Monday, June 4, 2012

How To: Execute command line in C#, get STD OUT results


How do I execute a command-line program from C# and get back the STD OUT results. Specifically, I want to execute DIFF on two files that are programmatically selected and write the results to a text box. Yes, I could figure this out for myself, but surely someone else has done something like it and I'm lazy...



Source: Tips4all

9 comments:

  1. // Start the child process.
    Process p = new Process();
    // Redirect the output stream of the child process.
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.FileName = "YOURBATCHFILE.bat";
    p.Start();
    // Do not wait for the child process to exit before
    // reading to the end of its redirected stream.
    // p.WaitForExit();
    // Read the output stream first and then wait.
    string output = p.StandardOutput.ReadToEnd();
    p.WaitForExit();


    Code is from MSDN.

    ReplyDelete
  2. Here's a quick sample:

    //Create process
    System.Diagnostics.Process pProcess = new System.Diagnostics.Process();

    //strCommand is path and file name of command to run
    pProcess.StartInfo.FileName = strCommand;

    //strCommandParameters are parameters to pass to program
    pProcess.StartInfo.Arguments = strCommandParameters;

    pProcess.StartInfo.UseShellExecute = false;

    //Set output of program to be written to process output stream
    pProcess.StartInfo.RedirectStandardOutput = true;

    //Optional
    pProcess.StartInfo.WorkingDirectory = strWorkingDirectory;

    //Start the process
    pProcess.Start();

    //Get program output
    string strOutput = pProcess.StandardOutput.ReadToEnd();

    //Wait for process to finish
    pProcess.WaitForExit();

    ReplyDelete
  3. There one other parameter I found useful, which I use to eliminate the process window

    pProcess.StartInfo.CreateNoWindow = true;


    this helps to hide the black console window from user completely, if that is what you desire.

    ReplyDelete
  4. System.Diagnostics.ProcessStartInfo psi =
    new System.Diagnostics.ProcessStartInfo(@"program_to_call.exe");
    psi.RedirectStandardOutput = true;
    psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
    psi.UseShellExecute = false;
    System.Diagnostics.Process proc System.Diagnostics.Process.Start(psi);;
    System.IO.StreamReader myOutput = proc.StandardOutput;
    proc.WaitForExit(2000);
    if (proc.HasExited)
    {
    string output = myOutput.ReadToEnd();
    }

    ReplyDelete
  5. You can launch any command line program using the Process class, and set the StandardOutput property of the Process instance with a stream reader you create (either based on a string or a memory location). After the process completes, you can then do whatever diff you need to on that stream.

    ReplyDelete
  6. You will need to use ProcessStartInfo with RedirectStandardOutput enabled - then you can read the output stream. You might find it easier to use ">" to redirect the output to a file (via the OS), and then simply read the file.

    [edit: like what Ray did: +1]

    ReplyDelete
  7. // usage
    const string ToolFileName = "example.exe";
    string output = RunExternalExe(ToolFileName);

    public string RunExternalExe(string filename, string arguments = null)
    {
    var process = new Process();

    process.StartInfo.FileName = filename;
    if (!string.IsNullOrEmpty(arguments))
    {
    process.StartInfo.Arguments = arguments;
    }

    process.StartInfo.CreateNoWindow = true;
    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    process.StartInfo.UseShellExecute = false;

    process.StartInfo.RedirectStandardError = true;
    process.StartInfo.RedirectStandardOutput = true;
    var stdOutput = new StringBuilder();
    process.OutputDataReceived += (sender, args) => stdOutput.Append(args.Data);

    string stdError = null;
    try
    {
    process.Start();
    process.BeginOutputReadLine();
    stdError = process.StandardError.ReadToEnd();
    process.WaitForExit();
    }
    catch (Exception e)
    {
    throw new Exception("OS error while executing " + Format(filename, arguments)+ ": " + e.Message, e);
    }

    if (process.ExitCode == 0)
    {
    return stdOutput.ToString();
    }
    else
    {
    var message = new StringBuilder();

    if (!string.IsNullOrEmpty(stdError))
    {
    message.AppendLine(stdError);
    }

    if (stdOutput.Length != 0)
    {
    message.AppendLine("Std output:");
    message.AppendLine(stdOutput.ToString());
    }

    throw new Exception(Format(filename, arguments) + " finished with exit code = " + process.ExitCode + ": " + message);
    }
    }

    private string Format(string filename, string arguments)
    {
    return "'" + filename +
    ((string.IsNullOrEmpty(arguments)) ? string.Empty : " " + arguments) +
    "'";
    }

    ReplyDelete
  8. This may not be the best/easiest way, but may be an option:

    When you execute from your code, add " > output.txt" and then read in the output.txt file.

    ReplyDelete
  9. There is a ProcessHelper Class in PublicDomain open source code which might interest you.

    ReplyDelete