Background
I have a code that runs an executable asynchronously. The executable would normally be run on the command line. My code is inspired by this post:
namespace Feather
{
    internal class Helper
    {
        private static StringBuilder output;
        private static Process cmd;
        public static void RunLogic(string args)
        {
            output = new StringBuilder();
            cmd = new Process();
            try
            {
                cmd.StartInfo.FileName = "Cotton.exe";
                cmd.StartInfo.Arguments = args;
                cmd.StartInfo.UseShellExecute = false;
                cmd.StartInfo.CreateNoWindow = true;
                cmd.StartInfo.RedirectStandardOutput = true;
                cmd.StartInfo.RedirectStandardInput = true;
                cmd.EnableRaisingEvents = true;
                cmd.OutputDataReceived +=
                   new DataReceivedEventHandler(cmd_OutputDataReceived);
                cmd.Exited += new EventHandler(cmd_Exited);
                cmd.Start();
            }
            catch (Exception ex)
            {
                RhinoApp.WriteLine("Error on process start: {0}", ex.Message);
            }
        }
        private static void cmd_Exited(object sender, EventArgs e)
        {
            try
            {
                if (!string.IsNullOrEmpty(output.ToString()))
                {
                    RhinoApp.WriteLine("Process output: {0}", output.ToString());
                }
                RhinoApp.WriteLine("Process finished.");
                cmd.Dispose();
            }
            catch (Exception ex)
            {
                RhinoApp.WriteLine("Error on process exit: {0}", ex.Message);
            }
        }
        private static void cmd_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            try
            {
                RhinoApp.WriteLine("cmd_OutputDataReceived is called.");
                if (!String.IsNullOrEmpty(e.Data))
                {
                    output.Append(e.Data + Environment.NewLine);
                }
            }
            catch (Exception ex)
            {
                RhinoApp.WriteLine("Error on process data-receive: {0}", ex.Message);
            }
        }
    }
}
Question
The private static StringBuilder output; is always empty. Nothing is appended to it by output.Append(e.Data + Environment.NewLine); statement. I cannot figure out why.
How can I get all the executable command line logs? Is there a straightforward way to do so?
