【问题标题】:Is it possible to intercept console output without third party libraries?是否可以在没有第三方库的情况下拦截控制台输出?
【发布时间】:2015-01-23 14:27:52
【问题描述】:

首先,this question 似乎是一个骗子,但事实并非如此。

我正在寻找一种拦截控制台输出的方法,以便在将字符串写入控制台的输出流之前进行一些字符串预处理。例如,我编写了一个将字符串包装为 X 个字符的方法,但我不想每次我认为可能需要它时都调用它。我链接的问题满足接收输出流的第一个条件,但它不允许我在应用预处理后执行我自己的Console.Write()

所以我想出了创建自己的类的想法,该类继承自 StringWriter 并覆盖 Write(string value) 重载,但我的断点似乎没有被命中。

class MyWriter : StringWriter
{
    public override void Write(string value)
    {
        var o = Console.Out;
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()));
        Console.WriteLine(value);
        Console.SetOut(o);
    }
}

static MyWriter output = new MyWriter();

static void Main(string[] args)
{
    Console.SetOut(output);

    Console.WriteLine("woooo");

    string s = output.ToString();
}

它正在写入流,但我的过载没有被击中。但是,如果我调用output.Write("woooo"),它确实会到达断点。这告诉我控制台没有调用我重载的特定方法。我究竟做错了什么?此外,在我的重写方法中交换输出对象似乎不起作用,但这是我必须解决的另一个问题。

我想尽可能避免使用任何第三方库。

【问题讨论】:

  • 你的代码太混乱了。为什么要为每个写入操作创建新流?我也不明白问题是什么。当你的 write 没有被调用?您是否尝试过重载其他方法?我也怀疑这是XY problem。你能解释一下你想要实现的目标吗?

标签: .net console-application


【解决方案1】:

您在MyWriter 类中创建了一个重载,但您仍在调用Console.WriteLine()。就像您在问题中提到的那样,您需要致电 output.Write() 来使用您的重载。

【讨论】:

    【解决方案2】:

    您似乎在假设 WriteLine 最终会调用 Writer 的 Write 方法。您需要覆盖 Write & WriteLine。这个问题有一个工作示例:Redirect console.writeline from windows application to a string

    【讨论】:

      【解决方案3】:

      是的。
      我通常只创建一个类,我可以将它包裹在 IDisposable 中。
      所以我可以在不修改其余代码的情况下将控制台输出记录到文件中。
      这样,我在控制台和文本文件中都有输出供以后参考。

      public class Program
      {
      
          public static async System.Threading.Tasks.Task Main(string[] args)
          {
              using (ConsoleOutputMultiplexer co = new ConsoleOutputMultiplexer())
              {
                  // Do something here
                  System.Console.WriteLine("Hello Logfile and Console 1 !");
                  System.Console.WriteLine("Hello Logfile and Console 2 !");
                  System.Console.WriteLine("Hello Logfile and Console 3 !");
              } // End Using co 
      
      
              System.Console.WriteLine(" --- Press any key to continue --- ");
              System.Console.ReadKey();
      
              await System.Threading.Tasks.Task.CompletedTask;
          } // End Task Main 
      
      }
      

      public class MultiTextWriter
          : System.IO.TextWriter
      {
      
          protected System.Text.Encoding m_encoding;
          protected System.Collections.Generic.IEnumerable<System.IO.TextWriter> m_writers;
      
      
          public override System.Text.Encoding Encoding => this.m_encoding;
      
      
          public override System.IFormatProvider FormatProvider
          {
              get
              {
                  return base.FormatProvider;
              }
          }
      
      
          public MultiTextWriter(System.Collections.Generic.IEnumerable<System.IO.TextWriter> textWriters, System.Text.Encoding encoding)
          {
              this.m_writers = textWriters;
              this.m_encoding = encoding;
          }
      
      
          public MultiTextWriter(System.Collections.Generic.IEnumerable<System.IO.TextWriter> textWriters)
              : this(textWriters, textWriters.GetEnumerator().Current.Encoding)
          { }
      
      
          public MultiTextWriter(System.Text.Encoding enc, params System.IO.TextWriter[] textWriters)
              : this((System.Collections.Generic.IEnumerable<System.IO.TextWriter>)textWriters, enc)
          { }
      
      
          public MultiTextWriter(params System.IO.TextWriter[] textWriters)
              : this((System.Collections.Generic.IEnumerable<System.IO.TextWriter>)textWriters)
          { }
      
      
          public override void Flush()
          {
              foreach (System.IO.TextWriter thisWriter in this.m_writers)
              {
                  thisWriter.Flush();
              }
          }
      
          public async override System.Threading.Tasks.Task FlushAsync()
          {
              foreach (System.IO.TextWriter thisWriter in this.m_writers)
              {
                  await thisWriter.FlushAsync();
              }
      
              await System.Threading.Tasks.Task.CompletedTask;
          }
      
      
          public override void Write(char[] buffer, int index, int count)
          {
              foreach (System.IO.TextWriter thisWriter in this.m_writers)
              {
                  thisWriter.Write(buffer, index, count);
              }
          }
      
      
          public override void Write(System.ReadOnlySpan<char> buffer)
          {
              foreach (System.IO.TextWriter thisWriter in this.m_writers)
              {
                  thisWriter.Write(buffer);
              }
          }
      
      
          public async override System.Threading.Tasks.Task WriteAsync(char[] buffer, int index, int count)
          {
              foreach (System.IO.TextWriter thisWriter in this.m_writers)
              {
                  await thisWriter.WriteAsync(buffer, index, count);
              }
      
              await System.Threading.Tasks.Task.CompletedTask;
          }
      
      
          public async override System.Threading.Tasks.Task WriteAsync(System.ReadOnlyMemory<char> buffer, System.Threading.CancellationToken cancellationToken = default)
          {
              foreach (System.IO.TextWriter thisWriter in this.m_writers)
              {
                  await thisWriter.WriteAsync(buffer, cancellationToken);
              }
      
              await System.Threading.Tasks.Task.CompletedTask;
          }
      
      
          protected override void Dispose(bool disposing)
          {
              foreach (System.IO.TextWriter thisWriter in this.m_writers)
              {
                  thisWriter.Dispose();
              }
          }
      
      
          public async override System.Threading.Tasks.ValueTask DisposeAsync()
          {
              foreach (System.IO.TextWriter thisWriter in this.m_writers)
              {
                  await thisWriter.DisposeAsync();
              }
      
              await System.Threading.Tasks.Task.CompletedTask;
          }
      
          public override void Close()
          {
      
              foreach (System.IO.TextWriter thisWriter in this.m_writers)
              {
                  thisWriter.Close();
              }
              
          } // End Sub Close 
      
      
      } // End Class MultiTextWriter 
      
      
      
      public class ConsoleOutputMultiplexer
          : System.IDisposable
      {
      
          protected System.IO.TextWriter m_oldOut;
          protected System.IO.FileStream m_logStream;
          protected System.IO.StreamWriter m_logWriter;
      
          protected MultiTextWriter m_multiPlexer;
      
      
          public ConsoleOutputMultiplexer()
          {
              this.m_oldOut = System.Console.Out;
      
              try
              {
                  this.m_logStream = new System.IO.FileStream("./Redirect.txt", System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write);
                  this.m_logWriter = new System.IO.StreamWriter(this.m_logStream);
                  this.m_multiPlexer = new MultiTextWriter(this.m_oldOut.Encoding, this.m_oldOut, this.m_logWriter);
      
                  System.Console.SetOut(this.m_multiPlexer);
              }
              catch (System.Exception e)
              {
                  System.Console.WriteLine("Cannot open Redirect.txt for writing");
                  System.Console.WriteLine(e.Message);
                  return;
              }
      
          } // End Constructor 
      
      
          void System.IDisposable.Dispose()
          {
              System.Console.SetOut(this.m_oldOut);
      
              if (this.m_multiPlexer != null)
              {
                  this.m_multiPlexer.Flush();
                  if (this.m_logStream != null)
                      this.m_logStream.Flush();
      
                  this.m_multiPlexer.Close();
              }
              
              if(this.m_logStream != null)
                  this.m_logStream.Close();
          } // End Sub Dispose 
      
      
      } // End Class ConsoleOutputMultiplexer 
      

      【讨论】:

        猜你喜欢
        • 2011-08-26
        • 1970-01-01
        • 2013-05-03
        • 1970-01-01
        • 1970-01-01
        • 2016-11-22
        • 1970-01-01
        • 2017-03-17
        • 2015-01-09
        相关资源
        最近更新 更多