0

I need to capture the event when my application is trying to write something on console.

Console.WriteLine("Any text");

Is it possible to get the text sent to console output in an event or method?

Fenton
  • 241,084
  • 71
  • 387
  • 401
D J
  • 6,908
  • 13
  • 43
  • 75
  • You can [redirect the `Console.Out`](http://stackoverflow.com/questions/6024172/is-it-possible-to-intercept-console-output) – PHeiberg Nov 06 '12 at 10:19
  • Here, try this, is some what similar to your requirement. http://stackoverflow.com/questions/11911660/redirect-console-writeline-from-windows-application-to-a-string – Ali Hasan Nov 06 '12 at 10:20

3 Answers3

1

One approach would be to create a new stream override, as shown in this article:

http://mel-green.com/2010/01/progressstream/

Then, you would need to set this as the stream that Console writes to, e.g.

MemoryStream ms = new MemoryStream();
ProgressStream progressStream = new ProgressStream(ms);
Console.SetOut(new StreamWriter(progressStream));

Then use the events of the progress stream to see when it is written to.

cuongle
  • 74,024
  • 28
  • 151
  • 206
Justin Harvey
  • 14,446
  • 2
  • 27
  • 30
  • Actually there are third party references. They are just using Console.WriteLine. I have included those dlls. So I can not apply this solution as I cant modify them. – D J Nov 07 '12 at 02:07
  • Third party references? I don't see any any, all the source is there. I am not really sure what you mean. – Justin Harvey Nov 07 '12 at 09:00
0

This may be helpful to you:

using System;
using System.IO;

namespace nsStreams
{
    public class Redirect
    {
        static public void Main ()
        {
            FileStream ostrm;
            StreamWriter writer;
            TextWriter oldOut = Console.Out;
            try
            {
                ostrm = new FileStream ("./Target.txt", FileMode.OpenOrCreate, FileAccess.Write);
                writer = new StreamWriter (ostrm);
            }
            catch (Exception e)
            {
                Console.WriteLine (e.Message);
                return;
            }
            Console.SetOut (writer);

            Console.SetOut (oldOut);
            writer.Close();
            ostrm.Close();
            Console.WriteLine ("Done");
        }
    }
}
sohel khalifa
  • 5,602
  • 3
  • 34
  • 46
0

Here is an example I used to make a thread-safe listener for Console content that we're "printing" into an observable collection that a WPF Element is bound to.

Create a custom TextWriter class so you can hook into the process:

public class CustomTextWriter : TextWriter
{
    private readonly StringBuilder lineBuffer = new();

    public event EventHandler<StringEventArgs>? LogModelReadyToAdd;

    public override Encoding Encoding => Encoding.UTF8;

    public override void Write(char value)
    {
        // This is the inner-most write, as it is down to a single character
        if (value is '\r' or '\n')
        {
            if (lineBuffer.Length > 0)
            {
                LogModelReadyToAdd?.Invoke(
                    this,
                    new(lineBuffer.ToString()));
                lineBuffer.Clear();
            }
            return;
        }
        lineBuffer.Append(value);
    }
}

With a quick string event args object:

public class StringEventArgs : EventArgs
{
    public StringEventArgs()
    {
    }

    public StringEventArgs(string @string)
    {
        String = @string;
    }

    public string? String { get; init; }
}

And in my main window (where the context is for me to bind, I have this in my OnInitialized):

CustomTextWriter writer = new();
writer.LogModelReadyToAdd += async (_, args) =>
{
    if (Application.Current.CheckAccess())
    {
        TheContext.StepLog?.Add(new() { Log = args.String, });
        return;
    }
    await Application.Current.Dispatcher.BeginInvoke(
        DispatcherPriority.Background,
        new Action(() => TheContext.StepLog?.Add(new() { Log = args.String, })));
};
Console.SetOut(writer);
James Gray
  • 334
  • 3
  • 9