See std::cout of .exe

2019-04-29 13:03发布

问题:

I have a .exe file that I've compiled on windows. But when I run it from the command line I don't see any of the things my program outputs to std::cout or std::cerr. The program runs and continues to run even after the command line returns to the prompt (it's a GUI program and doesn't quit until I press the quit button). How can I see the output of my program?

I'm using cmake to make a visual studio project which I then compile with msbuild.

回答1:

The simplest approach is to rebuild the program as a console application. The option to link.exe needs to be /SUBSYSTEM:CONSOLE instead of /SUBSYSTEM:WINDOWS; presumably there is a straightforward way of specifying this in cmake.

This change shouldn't affect your GUI at all, but it will cause Windows to allocate a console if the process isn't already associated with one. Also, command line shells will usually wait for console applications to exit before continuing.

The other approach is to call AllocConsole to explicitly create a new console, or AttachConsole if you want to use an existing one. Or, of course, you could send the output to a log file.

Additional

According to a Google search, you can build the program as a console application by adding the following line to your source code:

#pragma comment(linker, "/SUBSYSTEM:CONSOLE")

This is probably the easiest solution. You can put it in an #if block if you only want the console for debug builds.

See also CMake: How to use different ADD_EXECUTABLE for debug build?



回答2:

Harry Johnston's answer is spot-on if you want to permanently alter your application to display this information. I would recommend the latter approach he suggests, because switching your app to targeting the console subsystem will cause it to always allocate and display a console window on startup, even if you don't want it to.

However, I notice that you mention you want to display output from std::cerr, which implies that you might be only interested in this information for debugging purposes. In that case, my recommendation would be to call the OutputDebugString function instead of outputting to either std::cout or std::cerr. Then, you can use a little utility like DebugView to monitor the debug output of your application. Everything it sends to the OutputDebugString function will be displayed in the DebugView window.

If you want to use this setup with minimal changes to your existing code base, you can actually redirect the output of streams like std::cout and std::cerr to the debugger, just as if you'd called the OutputDebugString function. Advice on how to do this can be found in the answers to this question and in this blog post.



回答3:

One way to see the output is to run:

program.exe > output.txt 

and then monitor that file for the output. Or use a pipe to view it:

program.exe | find /v ""

To also monitor the error output you could use

program.exe > output.txt 2>&1

program.exe 2>&1 | find /v ""

I figured it out based on the documentation by Microsoft that leaves a lot to the imagination and from the much more practical examples here and here.

This helps me see "hidden" stdout and stderr messages from my (and other peoples) windows applications. It's interesting to see what messages have been left in some programs, but usually aren't seen.



回答4:

Windows doesn't support dual mode. Which means that when you run gui, you cannot get output to your console that you run the app from.