4

I have a Qt application in Visual Studio 2005 which is linked using \subsystem:windows such that when I run the compiled executable it does not create a command line terminal, as well.

I would like to create a command-line mode: when I start it with the --nogui command line argument, then the GUI is not presented, but a simple command-line program is run. Since the linking uses /subsystem:windows, the command line mode doesn't show any of the std::cout outputs unless I link my executable with \subsystem:console.

Is there a way to set the compilation/linking such that the same executable can either present the GUI windows or behave as a console application based on command-line parameters?

PS. I use Qt 4.2.0 and Visual Studio 2005 and the project is in C++.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
balint.miklos
  • 1,867
  • 1
  • 19
  • 23

4 Answers4

5

I think the preferred technique for the situation here is the ".com" and ".exe" method. In Windows from the command line, if you run a program and don't specify an extension, the order of precedence in locating the executable will .com preferred over a .exe file.

Then you can use tricks to have that ".com" be a proxy for the stdin/stdout/stderr and launch the same-named .exe file. This give the behavior of allowing the program to preform in a command-line mode when called form a console (potentially only when certain command-line arguments are detected) while still being able to launch as a GUI application free of a console.

There are various articles describing this, like "How to make an application as both GUI and Console application?" (see references in link below).

I hosted a project called dualsubsystem on google code that updates an old codeguru solution of this technique and provides the source code and working example binaries.

I hope that is helpful!

Community
  • 1
  • 1
gabeiscoding
  • 524
  • 5
  • 9
3

You can't. See this article by Raymond Chen:

How do I write a program that can be run either as a console or a GUI application?

For the reasons given in this article you sometimes see two versions of the same tool provided, one suffixed with 'w' such as in java.exe and javaw.exe on Windows.

However you might implement this clever workaround: How to make an application as both GUI and Console application.

Glenn Slayden
  • 17,543
  • 3
  • 114
  • 108
Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
  • Sorry, but this information is simply wrong in this particular, and `AllocConsole` will work just fine. What it doesn't do is create a new console when none exists – but this was not asked (since an extra argument has to be entered here to launch the console version anyway). Several people have also made this comment to Raymond's post. – Konrad Rudolph Apr 21 '09 at 14:38
  • Sorry, I meant `AttachConsole`, *not* `AllocConsole` (the latter does something else). Also, I forgot a word: "case". – Konrad Rudolph Apr 21 '09 at 14:40
  • @Konrad: From my understanding `AttachConsole` would only work if your parent process is cmd.exe, i.e. starting the application with --nogui from a shortcut would not work. IMHO there is no general solution to this problem, only some workarounds. – Dirk Vollmar Apr 21 '09 at 15:27
  • @divo: your understanding is indeed correct (although it would still be possible to fall back to `AllocConsole` if the parent process isn't cmd.exe -- an information that can be retrieved using other WinAPI functions). – Konrad Rudolph Apr 22 '09 at 12:07
1

Have you tried calling AttachConsole in your program to get the output redirected to the calling terminal?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • could you please give me a hint what header files and macro definition I need to be able to use AttachConsole? I tried #include #include , but apparently that is not enough to find AttachConsole function – balint.miklos Apr 21 '09 at 11:36
  • The documentation says to include `` and this is definitely enough. Did you forget the argument when calling the function? – Konrad Rudolph Apr 21 '09 at 11:46
  • AllocConsole() may also be appropriate: http://msdn.microsoft.com/en-us/library/ms681944.aspx – Raphaël Saint-Pierre Apr 21 '09 at 12:26
  • The AllocConsole() works for me, and opens a new console even if I start from a console. Anyway thanks for the answer – balint.miklos Apr 21 '09 at 13:02
  • I did try it with AttachConsole(ATTACH_PARENT_PROCESS) but the compiler told me doesn't find the identifier AttachConsole... with #include – balint.miklos Apr 21 '09 at 16:41
0

To use AttachConsole, you need to include the following line before including <windows.h>:

//Require at least Windows XP
#define _WIN32_WINNT 0x0501
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bruce
  • 1
  • 1