Given an existing Win32 GUI application, how can I see the messages it sends to stdout and stderr (file descriptors 1 and 2, cout and cerr, etc.)?
I cannot modify the application itself, and I know it simply calls C's printf internally.
There are a few similar questions already (e.g. here or here), but the solutions suggest modifying the executable. One answer from 2009 to a similar question recommends using DebugView, but I couldn't get it to display the actual stdout of the process, only kernel and system messages.
For background, I have a GUI application that was compiled a few years ago. The author didn't really know how Windows apps work, and so he just compiled his Linux code into an EXE. His code follows the Unix convention of sending debug messages to stdout while displaying graphics at the same time. Now the app broke, and it seems the relevant into should be in stdout, but I can't view it. I don't have the sources so I can't recompile it.
A minimal example
// main.c
#include <stdio.h>
int main() // sic, not WinMain()
{
printf("%s\n", "Hello World!");
return 0;
}
compiled as
mingw main.c -mwindows
produces a.exe. How can I launch a.exe, without modifying its source code, to be able to see the message?
Related
I've got a Windows application with a GUI written in Rust and winapi. Despite its GUI, it behaves like a console application. When the exe file is started, a Command Prompt window pops up, and the application is run from it. This is not what I want; a main window should open instead, as in all real desktop apps. How can I achieve this goal in Rust with winapi?
I've investigated some options. You can develop Windows desktop applications using Tauri or gtk-rs, but both of these techniques have drawbacks when used for Windows apps. More options may be found here. I've also tried the windows-rs samples available on the internet, but they're all console apps with a graphical user interface, which isn't what I'm looking for.
I also note that C++ desktop applications use the function int APIENTRY wWinMain(...) as the entry point while console applications use int main(...), and wWinMain doesn't seem available in rust winapi.
Whether the system allocates a console for a newly created process is controlled by the Subsystem field in the Windows-specific optional PE header. The field is populated through the linker's /SUBSYSTEM command line option. The only relevant arguments for desktop applications are CONSOLE and WINDOWS. The former instructs the system to allocate a console on launch, whereas the latter won't.
You can instruct the linker to target the WINDOWS subsystem from Rust code by placing the per-module
#![windows_subsystem = "windows"]
attribute (see windows-subsystem) inside the main module of your application.
You'll find an example of this in the core_app sample of the windows crate.
This is the most convenient way to target the WINDOWS subsystem. You can also explicitly pass the linker flag along, e.g. by placing the following override into .cargo/config.toml:
[build]
rustflags = [
"-C", "link-arg=/SUBSYSTEM:WINDOWS",
]
This may or may not work, depending on the linker you happen to be using. Since the linker isn't part of the Rust toolchain, making sure that this works and has the intended effect is on you.
A note on the entry point's function name: It is irrelevant as far as the OS loader is concerned. It never even makes it into the final executable image anyway. The PE image only stores the (image-base-relative) AddressOfEntryPoint, and that symbol could have been named anything.
The concrete name is only relevant to the build tools involved in generating the respective linker input.
More info here: WinMain is just the conventional name for the Win32 process entry point. The underlying principles apply to Rust just the same, particularly the aspect that the user-defined entry point (fn main()) isn't actually the executable's entry point.
I'm writing some software that involves Qt, GStreamer, and RTI Connext DDS. On Windows the code hangs at a certain point under certain circumstances.
Just before this happens, the message "Buffer creation failed" is printed on the console. However, this message does not occur in my code, so I assume it is generated by a dependency.
I've attached the Visual Studio debugger to the process, but because DDS is a proprietary library that was compiled in release mode, I have to compile all my code in in release mode, so it appears there is very little information you have access to. I tried to set a breakpoint on printf and puts, but this never triggers.
On Linux I'd poke around with gdb, strace, strings, and what not to try and locate the source of the message, but on Windows I have really no idea how to do these things.
Is it possible, to in Windows, create a GUI program, which has it's entry point in 'main()'? How do I do this?
My use for this is that I want a cross-platform application, with one uniform entry point.
Write your application using main() and all the GUI calls in there that you would have used in WinMain. This will create an application with both a GUI and a console window.
Use the Windows SDK tool editbin /SUBSYSTEM:WINDOWS appname.exe to change the subsystem flag in the PE header, so Windows won't create a console window automatically.
If you want to have a working stdout for debug message or the like, you can either use freopen to direct stdout to a file, or AllocConsole when you decide a console window is needed (for example, after an error occurs).
BTW: This thread indicates that the DMD compiler will prefer main() over WinMain() anyway if it finds both.
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.
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.
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?
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.
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.
I'm working on a project using Ogre3D. We recently ported our project to MacOSX but there are some things that were linked to the Windows API. In particular I don't know how this should be translated:
#if defined( __WIN32__ ) || defined( _WIN32 )
AllocConsole();
#endif
It would be nice to port the project under Linux someday, so is there an Unix-compatible way to allocate a console for standard output/input?
Thank you
From UNIX point of view, since I'm not that experienced in Mac-specific development.
A console is "allocated" by default. You cannot order the OS to open a console though. You could tell the IDE you are using to open it in a terminal, or, if it supports that, create your current application as a Console Application, despite using GUI.
What do I mean by saying that console is allocated by default? Each process actually gets its stdin, stdout and stderr (file identifiers 0, 1 and 2) from the calling process. So unless calling process (bash, Finder, whatever) conveniently forgets to leave those open, you always have a console open ... but perhaps invisible?
Easiest way to get a console is to launch the application from Terminal as Finder would do it from GUI. Remember, .apps are actually folders:
/projects/myapp$ ./BuiltApplication.app/Contents/MacOS/BuiltApplication
Finder sets the current working directory to the folder where the .app bundle is located, so the above emulates it all best.
Additionally, take a look at the Console application at /Applications/Utilities/Console.app, included with MacOS. Console is usually used for viewing stdout and stderr. I cannot test this since I'm not on Mac, but I've actually found some sources that say that stdout and stderr should be redirected there. See this post:
You can use Console.app to see the output of applications launched in the normal manner, because the launch infrastructure specifically sends their stdout and stderr there. You can also use the asl routines to query the log, or perform more sophisticated logging if you so desire.