Ok, so the idea is to change the reader / writer for the input and output of the console to do what they did before, but also write to the log file. I created a log class that should probably be expanded to take the file name / path as a parameter, but it is important to have it so that the output stream can be synchronized.
public class Log { private StreamWriter output; public Log() { output = new StreamWriter(File.OpenWrite("output.txt")); } public void Write(char c) { lock (output) { output.Write(c); } } public void Close() { output.Close(); } } public class MyConsoleOutput : TextWriter { private TextWriter standard; private Log log; public MyConsoleOutput(TextWriter standard, Log log) { this.standard = standard; this.log = log; } public override void Write(char value) { standard.Write(value); log.Write(value); } public override Encoding Encoding { get { return Encoding.Default; } } protected override void Dispose(bool disposing) { standard.Dispose(); } } public class MyConsoleInput : TextReader { private TextReader standard; private Log log; public MyConsoleInput(TextReader standard, Log log) { this.standard = standard; this.log = log; } public override int Peek() { return standard.Peek(); } public override int Read() { int result = standard.Read(); log.Write((char)result); return result; } protected override void Dispose(bool disposing) { standard.Dispose(); } }
Now that we have created these classes, we will do the following at the beginning of Main
:
Log log = new Log(); Console.SetOut(new MyConsoleOutput(Console.Out, log)); Console.SetIn(new MyConsoleInput(Console.In, log));
We will also need this at the end of Main
:
log.Close();
This is a somewhat quick and dirty drink. If you use this in production, you probably want to change a lot of class / method names.
Servy source share