代码之家  ›  专栏  ›  技术社区  ›  Jason Dagit

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

  •  61
  • Jason Dagit  · 技术社区  · 17 年前

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

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

    我看到,如果我在释放模式下运行,那么在程序退出后控制台窗口将保持打开状态,但在调试模式下,情况并非如此。

    我不想在我的程序中添加“系统”(“暂停”)或其他类似于读取字符的黑客。我只想让Visual Studio在使用调试运行测试后暂停,就像在发布模式下运行一样。如果测试的输出是在Visual Studio的一个输出窗口中捕获的,我也希望这样做,但这似乎比实际情况更困难。

    我该怎么做?

    16 回复  |  直到 8 年前
        1
  •  19
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

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

    这个技巧的好的副作用是它使您能够将测试失败视为编译错误。”…您可以使用通常用于编译错误分析的键盘快捷键/鼠标单击跳过这些错误…”

        2
  •  118
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

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

        3
  •  73
  •   Kirill Golikov    14 年前

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

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

        4
  •  10
  •   Kevin Timmerman    17 年前

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

        5
  •  8
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

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

    以下是我的工作内容:-)

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

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

    使用新的Visual Studio 2010,即使使用 Ctrl键 + F5 又名“无调试启动”。这很可能是因为您创建了“空项目”而不是“win32控制台应用程序”。如果将项目创建为“Win32控制台应用程序”,则可以忽略此项,因为它不适用。

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

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

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

        6
  •  5
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

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

        7
  •  3
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

    在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

    因此,我创建了我的自定义测试观察器,当断言失败或异常时,它将进入调试器。当我们在调试程序下运行时,在调试版本上启用了此功能。

    在我的单元测试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
  •  3
  •   Die in Sente    8 年前

    你说你不想用 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);
    

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

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

    注意:system()例程的Microsoft Visual Studio实现需要comspec环境变量来标识命令行解释器。如果这个环境变量搞得一团糟——例如,如果在Visual Studio项目的调试属性中有问题,这样在程序启动时环境变量就不会被正确传递下去——那么它只会安静地失败。

        9
  •  1
  •   Kibbee    17 年前

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

        10
  •  1
  •   dexblack    14 年前

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

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

    然后,不管控制台窗口是否出现,您的构建日志记录可以将单元测试输出保留为一个工件,用于检查失败的构建…

        11
  •  1
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

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

    包括 <time.h> 页眉:

    clock_t wait;
    
    wait = clock();
    while (clock() <= (wait + 5000)) // Wait for 5 seconds and then continue
        ;
    wait = 0;
    
        12
  •  0
  •   Andrew    17 年前

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

        13
  •  0
  •   Amanjit Gill    16 年前

    我用f11启动应用程序,并在unity-test-main.ipp(可以是汇编代码)的某个地方得到一个断点。我使用shift-f11(step out)运行单元测试,并获得CRT中的下一个汇编指令(通常在mainCrtstartup()中)。我用F9在那个指令上设置一个断点。

    在下一次调用时,我可以用f5启动应用程序,运行测试后应用程序将中断,因此给了我一个机会浏览控制台窗口。

        14
  •  0
  •   zurfyx    13 年前

    添加以下行将完成一个简单的MS-DOS pause 不显示任何消息。

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

    没有必要 Ctrl键 + F5 (这将使应用程序以发布模式运行)

        15
  •  0
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

    只需使用一个日志库,比如log4net,并将其记录到一个文件附加器中。

        16
  •  -1
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

    在结尾处做一个阅读行(就像我们在哥伦比亚说的那样,它是“forma cochina”,但它起作用):

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