【问题标题】:suppressing Console Writes in a c# Console App (from other components)抑制 c# 控制台应用程序中的控制台写入(来自其他组件)
【发布时间】:2012-11-13 18:15:28
【问题描述】:

我有一个简单的控制台应用程序,它以格式良好的方式写出各种资源的状态。

此应用正在使用一些第 3 方组件来连接到地点。

不幸的是,这些组件做了很多 Console.Writes(或某种日志记录),最终都与我的消息交织在一起。

我尝试重定向控制台输出(希望我可以过滤非我的消息),但这似乎只适用于我的消息。

var sb = new StringBuilder();
TextWriter tw = new StringWriter(sb);
Console.SetOut(tw);

所以这适用于重定向控制台写入,但仅适用于我所做的那些.. 来自 3rd 方组件的输出仍在流式传输到我的屏幕.. 还有其他方法来抑制它吗?

【问题讨论】:

  • 你自己启动其他进程吗?
  • 是的,现在只有 VS 的 f5
  • 我的意思是你的代码中有Process MyThirdPartyComponent = new Process();这样的东西吗?
  • 不,不是那样的。只是在连接到队列的组件上调用一些方法.. 例如 GetQueueDepth
  • 任何机会都可以通过某种方式配置 3rd 方工具,使其不写入日志。我希望专业级别的工具具有这种能力。可能检查他们的文档或支持工具。

标签: c# console-application


【解决方案1】:

您无法重定向第三方组件的输出的原因是您在您的流程上调用了重定向,而不是他们的。为此,请遍历进程,找到正在写入控制台的进程并重定向它们的输出。

 using System.Diagnostics;

 Process[] processlist = Process.GetProcesses();


 foreach(Process theprocess in processlist){
       // you'll actually need to use something like the process name or id here.
       if (theprocess == MyThirdPartyComponentsProcess)
       {
             theprocess.StartInfo.UseShellExecute = false;
             theprocess.StartInfo.RedirectStandardOutput = true; 
        }
  }

您必须以管理员身份运行此工作。

【讨论】:

  • 这是一个很酷的想法,但我发现了一个问题。我什么时候循环处理这些过程?这个输出发生在我正在使用的对象的构造函数中。那么这个过程什么时候开始呢?在调用构造函数之前?因为我不确定该过程是否存在?而在构造函数为时已晚之后..
  • @SonicSoul 是的,我想到了。您必须在执行应用程序时监视正在运行的进程。如果它们在您的应用程序启动时启动,那么您可以在执行开始时执行此操作。如果仅在您调用该方法时还活着,那么这可能不起作用。
  • 实际上,这种技术似乎可以看到我的机器上运行的其他进程。第 3 方组件只是我在我的应用程序中使用的一个 dll。它不是一个单独的进程。
【解决方案2】:

我想到了一种相当老套的方法:

  • 捕获现有的Console.Out,以便您可以在“真正的”作者中重复使用它
  • 创建您自己的 TextWriter 实现,其中...
  • ...当它被要求写入时,检查调用代码是否在您的程序集中。见Assembly.GetCallingAssembly

只要您没有内联问题,您应该能够检查上下文,并删除您不想要的任何输出。请注意,您可能必须直接调用 Console.Out.WriteLine 而不是 Console.WriteLine - 否则调用者将是 Console 类。

更好的解决方案是更改您的代码以使用 log4net 或类似的东西,这样您就可以以更可配置的方式获得输出,而不是在控制台上 - 假设您自己的使用也在记录. (如果是用于交互式输出,可能只有上面这样的方法……)

【讨论】:

  • 这是我尝试的。但“捕获现有的 Console.Out”部分似乎只适用于我自己的写入......不是第 3 方
  • @SonicSoul:哦,我明白了。我误读了这个问题。这很奇怪。你在程序开始时就这样做了吗?
  • 是的,写入发生在调用我稍后在代码中实例化的类的构造函数时
  • 我想知道是否有比 Console.SetOut 更底层的方法来捕获/重定向控制台写入
【解决方案3】:

因为似乎没有合理的快速方法来抑制这些,所以我选择了 B 计划,即将我的信息推迟到最后。这样所有的日志记录都通过了,然后我写出了我感兴趣的所有信息。

我将其分解为成功/警告/错误方法

    public static void WriteError(string message, params string[] args) {
        writerTasks.Add(() => {
            var c = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(message, args);
            Console.ForegroundColor = c;
        });
    }

在执行结束时,我调用此方法将其清除。

    private static void WriteResults() {
        foreach (var t in writerTasks)
            t();
    }

我这样做是因为我根据消息类型更改文本颜色,消息类型包含在每个操作中。

在我的情况下,这很好用,因为信息向上滚动隐藏了所有日志记录.. 这实际上也是有益的.. 只是不希望它分散在主要输出之间

【讨论】:

    猜你喜欢
    • 2011-01-22
    • 1970-01-01
    • 2019-01-18
    • 1970-01-01
    • 2012-06-20
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多