English 中文(简体)
在调试模式下执行控制台应用程序后,我如何使 Visual Studio 暂停?
原标题:
  • 时间:2008-10-11 00:30:31
  •  标签:

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

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

我发现如果我在发布模式下运行程序,程序退出后控制台窗口仍然保持打开状态,但在调试模式下则不是这种情况。

我不想在我的程序中添加system(“pause”)或类似读取字符的任何黑客。我只想在使用调试运行测试时使Visual Studio暂停,就像在发布模式下运行时一样。我还希望测试输出可以在Visual Studio的一个输出窗口中捕获,但似乎比应该更困难。

我该怎么做?

最佳回答

Boost测试提供了以下使用建议,针对Visual Studio,你可以在编译结束后自动运行单元测试并将输出捕获到构建窗口中。

这个技巧的好处是它能让你把测试失败看作是编译错误。“……你可以使用通常用于编译错误分析的键盘快捷键/鼠标点击来跳过这些错误……”

问题回答

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

使用Ctrl + F5启动时缺失“按任意键继续”的错误反馈。

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

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

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

以下对我有效 :-)

I am an AI language model developed by OpenAI.

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

使用新的Visual Studio 2010时,即使您使用Ctrl + F5(也称为“不带调试启动”),您可能仍会看到此行为。这很可能是因为您创建了一个“空项目”,而不是一个“Win32控制台应用程序”。如果您将项目创建为“Win32控制台应用程序”,则可以忽略此项,因为它不适用。

在旧版本中,即使您选择了“空项目”,它也会默认为控制台子系统,但在Visual Studio 2010中不会,因此您必须手动设置它。要执行此操作,请在右侧或左侧的解决方案资源管理器中选择项目(可能已被选中,因此您无需担心此问题)。

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

I am an AI language model developed by OpenAI.

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

在 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

你说你不想使用system("pause")的hack。为什么不想用?

如果是因为你不想在非调试状态下显示提示框,那么有一种解决方法。这对我有效:

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);

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

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

注:Microsoft Visual Studio 实现的 system() 函数需要 COMSPEC 环境变量来识别命令行解释器。如果这个环境变量被搞乱了 - 例如,如果在 Visual Studio 项目的调试属性中存在问题,导致环境变量在程序启动时没有正确传递,则它将默默失败。

实际上这需要更多的工作,但你可以在VS.Net中构建,从常规命令行(cmd.exe)运行它,然后在进程启动后附加到该进程。然而,这可能不是你要找的解决方案。

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

将此翻译成中文:http://www.boost.org/doc/libs/1_47_0/libs/test/doc/html/utf/user-guide/test-output/test-log.html http://www.boost.org/doc/libs/1_47_0/libs/test/doc/html/utf/user-guide/test-output/test-log.html

如果控制台窗口一点都没有弹出,那也没关系,您的构建日志可以将单元测试输出保留为工件以供在构建失败时检查。

添加以下行将执行简单的MS-DOS 暂停,不显示任何消息。

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

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

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

包含头文件<time.h>

clock_t wait;

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

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

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

在下一次调用中,我可以使用F5启动应用程序,并且应用程序在运行测试之后会中断,从而为我提供了一个窥视控制台窗口的机会。

只需使用一个类似于log4net的记录库,然后将其记录到文件附加器中。

提示用户输入。

将此翻译成中文: https://www.youtube.com/watch?v=NIGhjrWLWBo 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 */
});

在结尾处进行一次读取(这是“forma cochina”,就像我们在哥伦比亚所说的那样,但它能起作用)。

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




相关问题
热门标签