Redirect console.writeline from windows application to a string

前端 未结 4 1779
隐瞒了意图╮
隐瞒了意图╮ 2020-11-28 08:29

I have an external dll written in C# and I studied from the assemblies documentation that it writes its debug messages to the Console using Console.WriteLine.

相关标签:
4条回答
  • 2020-11-28 08:43

    You can also call SetOut with Console.OpenStandardOutput, this will restore the original output stream:

    Console.SetOut(new StreamWriter(Console.OpenStandardOutput()));
    
    0 讨论(0)
  • 2020-11-28 08:50

    Or you can wrap it up in a helper method that takes some code as an argument run it and returns the string that was printed. Notice how we gracefully handle exceptions.

    public string RunCodeReturnConsoleOut(Action code) 
    {
      string result;
      var originalConsoleOut = Console.Out;
      try 
      {
        using (var writer = new StringWriter()) 
        {
          Console.SetOut(writer);
          code();
          writer.Flush();
          result = writer.GetStringBuilder().ToString();
        }
        return result;
      }
      finally 
      {
        Console.SetOut(originalConsoleOut); 
      }
    }
    
    0 讨论(0)
  • 2020-11-28 08:52

    As it seems like you want to catch the Console output in realtime, I figured out that you might create your own TextWriter implementation that fires an event whenever a Write or WriteLine happens on the Console.

    The writer looks like this:

        public class ConsoleWriterEventArgs : EventArgs
        {
            public string Value { get; private set; }
            public ConsoleWriterEventArgs(string value)
            {
                Value = value;
            }
        }
    
        public class ConsoleWriter : TextWriter
        {
            public override Encoding Encoding { get { return Encoding.UTF8; } }
    
            public override void Write(string value)
            {
                if (WriteEvent != null) WriteEvent(this, new ConsoleWriterEventArgs(value));
                base.Write(value);
            }
    
            public override void WriteLine(string value)
            {
                if (WriteLineEvent != null) WriteLineEvent(this, new ConsoleWriterEventArgs(value));
                base.WriteLine(value);
            }
    
            public event EventHandler<ConsoleWriterEventArgs> WriteEvent;
            public event EventHandler<ConsoleWriterEventArgs> WriteLineEvent;
        }
    

    If it's a WinForm app, you can setup the writer and consume its events in the Program.cs like this:

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            using (var consoleWriter = new ConsoleWriter())
            {
                consoleWriter.WriteEvent += consoleWriter_WriteEvent;
                consoleWriter.WriteLineEvent += consoleWriter_WriteLineEvent;
    
                Console.SetOut(consoleWriter);
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
        }
    
        static void consoleWriter_WriteLineEvent(object sender, Program.ConsoleWriterEventArgs e)
        {
            MessageBox.Show(e.Value, "WriteLine");
        }
    
        static void consoleWriter_WriteEvent(object sender, Program.ConsoleWriterEventArgs e)
        {
            MessageBox.Show(e.Value, "Write");
        }
    
    0 讨论(0)
  • 2020-11-28 08:53

    It basically amounts to the following:

    var originalConsoleOut = Console.Out; // preserve the original stream
    using(var writer = new StringWriter())
    {
        Console.SetOut(writer);
    
        Console.WriteLine("some stuff"); // or make your DLL calls :)
    
        writer.Flush(); // when you're done, make sure everything is written out
    
        var myString = writer.GetStringBuilder().ToString();
    }
    
    Console.SetOut(originalConsoleOut); // restore Console.Out
    

    So in your case you'd set this up before making calls to your third-party DLL.

    0 讨论(0)
提交回复
热议问题