在调试模式下执行控制台应用程序后如何使Visual Studio暂停?

时间:2008-10-11 00:30:31

标签: c++ visual-studio unit-testing boost console

我有一组Boost单元测试,我想作为控制台应用程序运行。

当我正在进行项目并运行测试时,我希望能够调试测试,并且我希望在测试运行后让控制台保持打开状态。

我看到如果我在发布模式下运行,程序退出后控制台窗口会保持不变,但在调试模式下,情况并非如此。

我不想添加'system(“pause”);'或任何其他黑客,比如在我的节目中读一个角色。我只是想在调试运行测试之后使Visual Studio暂停,就像我在发布模式下运行一样。如果在Visual Studio的一个输出窗口中捕获测试的输出,我也会喜欢它,但这似乎也应该比它应该更难。

我该怎么做?

17 个答案:

答案 0 :(得分:120)

尝试使用 Ctrl + F5 组合运行应用程序。

答案 1 :(得分:73)

http://connect.microsoft.com/VisualStudio/feedback/details/540969/missing-press-any-key-to-continue-when-lauching-with-ctrl-f5

在旧版本中,即使您选择了“空项目”,它也会默认为控制台子系统,但在2010年则不会,因此您必须手动设置它。为此,请在右侧或左侧的解决方案资源管理器中选择项目(可能已经选中,因此您不必担心这一点)。然后从菜单栏下拉菜单中选择“项目”,然后选择“ project_name properties”> “配置属性”> “链接器”> “system”并设置第一个属性,将“子系统”属性下拉到“console(/ SUBSYSTEM:CONSOLE)”。控制台窗口现在应该像往常一样在执行后保持打开状态。

答案 2 :(得分:19)

Boost测试提供以下usage recommendations for Visual Studio,使您能够在编译结束时自动运行单元测试并将输出捕获到构建窗口中。

这个技巧的好处是它使您能够将测试失败视为编译错误。 “...您可以使用常用的键盘快捷键/鼠标点击来跳过这些错误,用于编译错误分析......”

答案 3 :(得分:10)

在最后一行代码上设置断点。

答案 4 :(得分:8)

我刚刚从http://social.msdn.microsoft.com/forums/en-US/Vsexpressvc/thread/1555ce45-8313-4669-a31e-b95b5d28c787/?prof=required复制了

以下适用于我: - )

/////////////////////////////////////////////// //////////////////////////////////////

这是控制台可能消失的另一个原因。解决方案:

使用新的Visual Studio 2010,即使使用 Ctrl + F5 aka“start without debugging”,您也可能会看到此行为。这很可能是因为您创建了一个“空项目”而不是“Win32控制台应用程序”。如果您将项目创建为“Win32控制台应用程序”,则可以忽略它,因为它不适用。

在旧版本中,即使您选择“空项目”,它也会默认使用控制台子系统,但在Visual Studio 2010中则不会,因此您必须手动设置它。为此,请在右侧或左侧选择解决方案资源管理器中的项目(可能已经选中,因此您不必担心这一点。)

然后从菜单栏下拉菜单中选择“项目”,然后选择“ project_name 属性”→“配置属性”→“链接器”→“系统”并设置第一个属性,即drop将“subsystem”属性改为“console(/ SUBSYSTEM:CONSOLE)”。控制台窗口现在应该像往常一样在执行后保持打开状态。

/////////////////////////////////////////////// //////////////////////////////////////

答案 5 :(得分:5)

如果是控制台应用程序,请使用 Ctrl + F5

答案 6 :(得分:3)

你说你不想使用system("pause")黑客。为什么不呢?

如果是因为您不希望程序在被调试时提示,那么可以解决这个问题。这对我有用:

void pause () {
    system ("pause");
}

int main (int argc, char ** argv) {
    // If "launched", then don't let the console close at the end until
    // the user has seen the report.
    // (See the MSDN ConGUI sample code)
    //
    do {
        HANDLE hConsoleOutput = ::GetStdHandle (STD_OUTPUT_HANDLE);
        if (INVALID_HANDLE_VALUE == hConsoleOutput)
            break;
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        if (0 == ::GetConsoleScreenBufferInfo (hConsoleOutput, &csbi))
            break;
        if (0 != csbi.dwCursorPosition.X)
            break;
        if (0 != csbi.dwCursorPosition.Y)
            break;
        if (csbi.dwSize.X <= 0)
            break;
        if (csbi.dwSize.Y <= 0)
            break;
        atexit (pause);
    } while (0);

我只是将此代码粘贴到我正在编写的每个新控制台应用程序中。如果正在从命令窗口运行程序,则光标位置将不是&lt; 0,0&gt;,并且它将不会调用atexit()。如果它已从您的调试器(任何调试器)启动,则控制台光标位置将为&lt; 0,0&gt;并且将执行atexit()来电。

我从以前在MSDN库中的示例程序中得到了这个想法,但我认为它已被删除。

注意:system()例程的Microsoft Visual Studio实现需要COMSPEC环境变量来标识命令行解释器。如果此环境变量搞砸了 - 例如,如果您在Visual Studio项目的调试属性中遇到问题,以便在启动程序时环境变量没有正确传递 - 那么它将无声地失败

答案 7 :(得分:3)

在Boost.Test中,有一个--auto_start_dbg参数用于在测试失败时(在异常或断言失败时)进入调试器。出于某种原因,它对我不起作用。

请参阅http://www.boost.org/doc/libs/1_40_0/libs/test/doc/html/utf/usage-recommendations/dot-net-specific.html

由于这个原因,我创建了自定义test_observer,当出现断言失败或异常时,它将进入调试器。当我们在调试器下运行时,这在调试版本上启用。

在我的单元测试EXE文件的一个源文件中,我添加了以下代码:

#ifdef _DEBUG

#include <boost/test/framework.hpp>
#include <boost/test/test_observer.hpp>

struct BoostUnitTestCrtBreakpointInDebug: boost::unit_test::test_observer
{
    BoostUnitTestCrtBreakpointInDebug()
    {
        boost::unit_test::framework::register_observer(*this);
    }

    virtual ~BoostUnitTestCrtBreakpointInDebug()
    {
        boost::unit_test::framework::deregister_observer(*this);
    }

    virtual void assertion_result( bool passed /* passed */ )
    {
        if (!passed)
            BreakIfInDebugger();
    }

    virtual void exception_caught( boost::execution_exception const& )
    {
        BreakIfInDebugger();
    }

    void BreakIfInDebugger()
    {
        if (IsDebuggerPresent())
        {
            /**
             * Hello, I know you are here staring at the debugger :)
             *
             * If you got here then there is an exception in your unit
             * test code. Walk the call stack to find the actual cause.
             */
            _CrtDbgBreak();
        }
    }
};

BOOST_GLOBAL_FIXTURE(BoostUnitTestCrtBreakpointInDebug);

#endif

答案 8 :(得分:1)

它实际上会更省力,但你可以在VS.Net中构建,从常规命令行(cmd.exe)运行它,然后在它开始运行后附加到进程。但这可能不是您正在寻找的解决方案。

答案 9 :(得分:1)

我会在你自己选择的特定时间(毫秒)内使用“等待”命令。应用程序将执行,直到您要检查的行,然后在时间到期后继续。

包含<time.h>标题:

clock_t wait;

wait = clock();
while (clock() <= (wait + 5000)) // Wait for 5 seconds and then continue
    ;
wait = 0;

答案 10 :(得分:1)

或者您可以使用boost_test“测试日志输出。”

http://www.boost.org/doc/libs/1_47_0/libs/test/doc/html/utf/user-guide/test-output/test-log.html

然后控制台窗口是否完全显示无关紧要您的构建日志记录可以将单元测试输出保存为用于检查失败构建的工件......

答案 11 :(得分:0)

只需使用日志库,如log4net,并将其记录到文件追加器。

答案 12 :(得分:0)

提示用户输入。

https://www.youtube.com/watch?v=NIGhjrWLWBo

显示如何针对C ++执行此操作。对于Node.js,这是直接从文档中提取的(并且有效):

'use strict';

console.log('Hello world');

const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.question('Press enter to continue...', (answer) => {
    rl.close(); /* discard the answer */
});

答案 13 :(得分:0)

添加以下行将执行一个不显示消息的简单MS-DOS pause

system("pause >nul | set /p \"=\"");

并且不需要 Ctrl + F5 (这将使您的应用程序在发布模式下运行)

答案 14 :(得分:0)

我使用F11启动应用程序并在unit_test_main.ipp中获取断点(可以是汇编代码)。我使用shift-f11(Step out)来运行单元测试并获得CRT中的下一个汇编指令(通常在mainCRTStartup()中)。我使用F9在该指令处设置断点。

在下次调用时,我可以使用F5启动应用程序,运行测试后应用程序将中断,因此让我有机会查看控制台窗口

答案 15 :(得分:0)

您还可以将可执行文件设置为外部工具,并将工具标记为使用输出窗口。这样,工具的输出将在Visual Studio本身中可见,而不是单独的窗口。

答案 16 :(得分:-1)

最后做一个readline(就像我们在哥伦比亚所说的那样“形成cochina”,但它有效):

static void Main(string[] args)
{
    .
    .
    .
    String temp = Console.ReadLine();
}