Console.WriteLine在Debug中的输出位置是什么?

35
我发现了这个问题(链接),但我想知道的不同 - Console.WriteLine的输出是否会出现在调试时? 我知道为了将它输出到输出窗口,我应该使用Debug.WriteLine()或其他方法,但是标准的Console.WriteLine()去哪里了呢? 编辑 当调试时,您看不到黑色控制台窗口/测试日志 - 因此真正的问题是:我如何在调试期间访问/查看此输出?

在 Visual Studio 的最上方菜单中选择 Debug > Windows > Output。它会显示所有 Console.WriteLine("Debug MyVariable: " + MyVariable) 当你到达它们时。在此之前设置断点,进行调试,然后使用 F11 逐行步进代码。 - s3c
11个回答

21

控制台可以将其输出重定向到任何文本编写器。如果您实现了一个编写到Diagnostics.Debug的文本编写器,那么您就做好了准备。

这是一个编写到调试器的文本编写器。

using System.Diagnostics;
using System.IO;
using System.Text;

namespace TestConsole
{
    public class DebugTextWriter : TextWriter
    {
        public override Encoding Encoding
        {
            get { return Encoding.UTF8; }
        }

        //Required
        public override void Write(char value)
        {
            Debug.Write(value);
        }

        //Added for efficiency
        public override void Write(string value)
        {
            Debug.Write(value);
        }

        //Added for efficiency
        public override void WriteLine(string value)
        {
            Debug.WriteLine(value);
        }
    }
}

由于它使用了Diagnostics.Debug,因此它将遵循您的编译器设置,决定是否输出任何内容。这些输出也可以在Sysinternals DebugView中看到。

以下是如何使用它:

using System;

namespace TestConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.SetOut(new DebugTextWriter());
            Console.WriteLine("This text goes to the Visual Studio output window.");
        }
    }
}

如果您想在Release模式下编译时查看Sysinternals DebugView的输出,您可以使用一个写入OutputDebugString API的TextWriter。代码可能如下所示:

using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace TestConsole
{
    public class OutputDebugStringTextWriter : TextWriter
    {
        [DllImport("kernel32.dll")]
        static extern void OutputDebugString(string lpOutputString);

        public override Encoding Encoding
        {
            get { return Encoding.UTF8; }
        }

        //Required
        public override void Write(char value)
        {
            OutputDebugString(value.ToString());
        }

        //Added for efficiency
        public override void Write(string value)
        {
            OutputDebugString(value);
        }

        //Added for efficiency
        public override void WriteLine(string value)
        {
            OutputDebugString(value);
        }
    }
}

它将遵循您的编译器设置,决定是否应该写入任何输出。输出会被发送到哪里? - jpaugh
1
@jpaugh 在调试时,Diagnostics.Debug 会将信息写入 Visual Studio 的输出窗口。发布编译通常会删除 Debug 语句。 - Carl R
啊,每个程序员都渴望做的事情 - 编写低级输出例程。 - john k

10
NullStream是一种“没有后备存储器”的流。所有方法均不执行任何操作或返回任何值。它是Stream的内部类。以下代码取自Microsoft的源代码。
基本上,当调用其中一个Console写入方法时,第一次会调用Windows API函数GetStdHandle以获取“标准输出”。如果没有返回处理,就创建并使用NullStream
Samuel的回答是正确的并提供了一般信息。要实际重定向控制台输出,无论项目类型如何,请使用Console.SetOut(New System.IO.StreamWriter("C:\ConsoleOutput.txt")),这是一个简单的示例。
将控制台,调试和跟踪指向文件
直接回答您的问题。使用ConsoleTraceListenerStreamWriter将所有三个输出指向文件。我仅在开发中使用以下内容。
    Dim oLogFile As New System.IO.StreamWriter("C:\ConsoleOutput.txt")
    oLogFile.AutoFlush = True 'so we do not have to worry about flushing before application exit

    Console.SetOut(oLogFile)

    'note, writing to debug and trace causes output on console, so you will get double output in log file
    Dim oListener As New ConsoleTraceListener
    Debug.Listeners.Add(oListener)
    Trace.Listeners.Add(oListener)

NullStream

[Serializable]
private sealed class NullStream : Stream {
    internal NullStream() { }

    public override bool CanRead {
        get { return true; }
    }

    public override bool CanWrite {
        get { return true; }
    }

    public override bool CanSeek {
        get { return true; }
    }

    public override long Length {
        get { return 0; }
    }

    public override long Position {
        get { return 0; }
        set { }
    }

    // No need to override Close

    public override void Flush() {
    }

    public override int Read([In, Out] byte[] buffer, int offset, int count) {
        return 0;
    }

    public override int ReadByte() {
        return -1;
    }

    public override void Write(byte[] buffer, int offset, int count) {
    }

    public override void WriteByte(byte value) {
    }

    public override long Seek(long offset, SeekOrigin origin) {
        return 0;
    }

    public override void SetLength(long length) {
    }
} 

5

对我来说最好的解决方案是将Console.WriteLine()更改为System.Diagnostics.Debug.WriteLine()。例如:

 catch (DbEntityValidationException dbEx)
 {
    foreach (var validationErrors in dbEx.EntityValidationErrors)
    {
       foreach (var validationError in validationErrors.ValidationErrors)
       {
          System.Diagnostics.Debug.WriteLine("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
       }
    }

然后你可以在输出窗口中将错误视为对象查看。

3
调试和发布不控制是否获得控制台窗口,这由项目的输出类型控制(属性-> 应用程序-> 输出类型)。 控制台应用程序将为您打开一个控制台窗口,该窗口将可视化并接收从窗口到 System.Console 中的错误、输入和输出流。 System.Console 类公开了几个属性和方法,即使您无法看到它们也可以与其流进行交互。其中最重要的是 Error、In、Out、SetError()、SetIn()、SetOut() 和 Read、Write 方法。

2
只需在您的命名空间中添加using System.Diagnostics;。然后,使用Debug而不是Console。
例如:Debug.WriteLine("Hello World");
最后,按Ctrl+Alt+O打开输出窗口。您的文本将在那里打印出来。该窗口通常出现在Visual Studio底部停靠,但可以拖出并移动到任何地方。
注意:在左上角会有一个下拉框,名为“Show output from:”
需要选择“Debug”。
或者,也可以通过选择视图选项卡并选择输出来打开输出窗口。

2
Visual Studio启动Windows程序(/target:winexe)时,将stdin/stdout/stderr重定向到命名管道。每个管道的另一端由VS调试器拥有,stderr/stdout上读取的任何内容都会显示在“调试输出”窗口中。因此,Console.Write自动出现在VS调试输出中。请注意,如果你附加到已经启动的进程上,这种情况不会发生(因为重定向技巧只能在进程启动时完成)。
当启动控制台程序(/target:exe)时,不会发生此重定向,因此Console.Write会输出到实际控制台(或者stdout被重定向到的地方)。
我找不到任何文档记录这种行为,这只是我的结论,是通过调查VS如何启动和调试应用程序得出的。

看起来VS2019将STDOUT重定向到“立即窗口”。 - dummy

1

0

它输出到控制台(标准输出)或者控制台所设置的流中。


12
我认为这个问题在询问:“哪个游戏机?”和“游戏机在哪里?” - ᴍᴀᴛᴛ ʙᴀᴋᴇʀ

0

如已在OP的问题中评论:

无需编写额外代码

在Visual Studio最上方的菜单中选择

调试 > 窗口 > 输出

输出窗口仅在调试模式下可见,它将显示所有例如 Console.WriteLine("Debug MyVariable: " + MyVariable) 当您到达它们时。

在(选定行的开头的不同颜色的空白区域)行号之前设置断点,调试(F5),然后逐行步进代码(F11),直到您找到问题所在。


-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接