如何在VS中捕获控制台输出以进行调试?

12
在VS的外部工具设置中,有一个“使用输出窗口”复选框,可以捕获工具命令行的输出并将其转储到VS选项卡中。
问题是:当我按F5键时,是否可以获得与我的程序相同的处理?
编辑:FWIW我在使用C#,但如果这对您的答案有影响,那么您的答案可能不是我要找的。
我想要的是将程序的输出流传输到VS的输出选项卡中,使用输出重定向('|'和'>')在cmd提示符中使用的相同设备。
6个回答

4
您应该能够将输出捕获到一个文本文件中并使用它。我没有方便使用的VS,所以这是从记忆中得出的:
1. 创建一个C++项目 2. 打开项目设置,调试选项卡 3. 启用托管调试 4. 编辑命令行添加 "> output.txt" 5. 在调试器下运行您的程序
如果一切都按照我记得的方式工作,那么这将重定向STDOUT到一个文件,即使您实际上没有在CMD.EXE下运行。
(调试器有自己的重定向语法实现,与cmd不完全相同,但它非常好。)
现在,如果您在VS中打开此文件,则仍然可以在VS中查看输出,尽管不是在您希望的完全相同的窗口中。

3
控制台可以将输出重定向到任何TextWriter。如果您实现一个写入Diagnostics.Debug的TextWriter,那么就可以使用它了。
这里是一个可以写入调试器的TextWriter。
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);
        }
    }
}

由于它使用诊断调试,因此它将遵循您的编译器设置,以确定是否应输出任何内容。这些输出也可以在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.");
        }
    }
}

如果您想在发布模式下编译时查看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);
        }
    }
}

1

也许这对你有用:在Main中的关闭}上设置一个断点,然后在它关闭之前查看控制台窗口。如果需要,甚至可以将文本复制出来。

在我用于开发的每台机器上,我都以某种方式配置我的控制台窗口,这恰好使这种方法更有效:

  1. 运行cmd.exe
  2. ALT-SPACE,D
  3. 在选项中启用快速编辑模式。
  4. 在布局中,将缓冲区高度设置为9999
  5. 点击确定
  6. 退出CMD窗口。

+1 用于控制台窗口的配置。我会将窗口大小的高度设置为50。 - AMissico

1

我在这里做出一些假设。首先,我认为您谈论的是应用程序中的printf输出(无论是来自控制台应用程序还是Windows GUI应用程序)。我的第二个假设是C语言。

据我所知,您不能直接将printf输出定向到dev studio的输出窗口。 [OP添加了强调]

可能有一种方法,但我不知道。不过,您可以将printf函数调用定向到自己的例程,该例程将

  1. 调用printf并打印字符串
  2. 调用OuputDebugString()将字符串打印到输出窗口

您可以采取几种方法来实现此目标。首先是编写自己的printf函数,然后调用printf和OuputDebugString()

void my_printf(const char *format, ...)
{
    char buf[2048];

    // get the arg list and format it into a string
    va_start(arglist, format);
    vsprintf_s(buf, 2048, format, arglist);
    va_end(arglist); 

    vprintf_s(buf);            // prints to the standard output stream
    OutputDebugString(buf);    // prints to the output window
}

上面的代码大部分都没有经过测试,但它应该能够传达概念。

如果你不是在使用C/C++,那么这种方法对你来说就行不通了。:-)


段落2似乎涵盖了这个。 - BCS
https://dev59.com/PHRB5IYBdhLWcg3wj36c 看起来描述了如何使其工作,不过使用OutputDebugString也很好用。 - rogerdpack

0

System.Diagnostics.Debug.Writeline() 或 Trace.Writeline()


1
我正在寻找一些可以在不修改输出代码的情况下正常工作的东西。 - BCS

0

您可以使用Systems.Diagnostics.Trace类将输出写入Output窗口,而不是(或者除此之外)控制台。它需要一些配置,但它可以工作。这符合您的要求吗?

您还可以按this article中所述添加自己的选项卡,但我从未尝试过。


那个链接也不是。糟糕。 - BCS

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