Using the console in a GUI app in windows, only if its run from a console - c++

My application is a GUI app that has helpful (though optional) information through the terminal (via cout).
In Windows I either have a console appear (by compiling as a console app, or allocating it dynamically) or I don't.
My intention is to make use of the console IF it is being run from the console, but ignore the console completely if it was not. (Essentially what happens in Linux and OS X).
I do not wish to redirect to a file (and in the case of using cin, this is not a viable solution anyway).
Is there a way to attach a GUI app in Windows to the console it is run from, if and only if it is run from a console?

and in the case of using cin, this is not a viable solution anyway
This is the killer detail in your question. It is simple on paper, just first call AttachConsole(ATTACH_PARENT_PROCESS) to try to attach to an existing console. That will fail when your program got started from a GUI program like Explorer or a desktop shortcut. So if it returns FALSE then call AllocConsole() to create your own console.
Using cin is a problem however. The command processor pays attention to your EXE and checks if it is console mode app or a GUI app. It will detect a GUI app in your case and then doesn't wait for the process to complete. It displays the prompt again and waits for input. You will then also wait for input but you'll lose, the command processor got there first. Your output is also intermingled with the command prompt, the easy problem to solve.
There's a simple workaround for that, your user should start your program with start /wait yourapp to tell the command processor to wait for the process to complete. Problem is: nobody ever uses that. And the user will not realize what happens when they type input, intending it to go into your program but it is actually interpreted by the command processor. Producing a mystifying error message or formatting the hard drive.
Only two good ways to solve this unsolvable problem. Either build your program as a console mode app and call FreeConsole() when you find out you want to display a GUI. Or always call AllocConsole(). These are not great alternatives. The first approach is the one used by the Java JVM on Windows. One of the oldest bugs filed against the JVM and driving Java programmers completely batty from the flashing console window.
The third alternative is the only decent one, and the one you don't want, create another EXE that will always use the console. Like Java does, javaw.exe vs java.exe.
A trick is possible, you can rename that file from "yourapp2.exe" to "yourapp.com". It will be picked first when the user types "yourapp" at the command line prompt, a desktop shortcut can still point to "yourapp.exe". Visual Studio uses this trick, devenv.com vs devenv.exe.

You can check CONSOLE_SCREEN_BUFFER_INFO (via GetConsoleScreenBufferInfo) on startup to determine if you've been run from within an existing console. If the buffer's position is 0,0, you were run from outside of the console. For details, see this Microsoft Knowledgebase Article which describes the process.
In order for this to work, you need to compile your application as a console application (using /SUBSYSTEM:CONSOLE), and then detach yourself from the console if the application started a new console (buffer at 0,0). This will cause the program to properly "attach" to the calling console when launched from a command line.

As others have pointed out you have to create a console app and a window app. So, you'd end up with console.exe and app.exe. To make it less obvious at the command-line, you can take advantage of the PATHEXT trick like devenv does. cmd.exe treats a file as a command if its extension is in the PATHEXT environment variable. COM is there by default so you could rename console.exe as app.com, allowing the command app to start the console app attached to the current console.
Note: Of course, a console app can show a GUI if desired.
The difference in the build between app.com and app.exe depends on your build system but it could just be the one attribute that sets the output type. With msbuild (for .vcxproj files), it's just a matter of another build configuration.

you can create an application in console that get a line using argc and prints it;
////
int main(int argc, char *argv[])
{
//here print argv....using cout or printf
}
save the file as console.exe in the folder of your app.
now in your app if you want to see any line in console you can call the command
system("console.exe this is the line i want to print and see in console");

Related

How do i make a C++ program open multiple CMD Prompts

This is kind of an odd question but does anyone know how to make a c++ program open multiple separate CMD prompts? they don't even have to be proper command prompts they can spit out text in a separate CMD like window that's fine. they don't need to talk to each other or do anything more than display text. the only reason I'm not doing this in Batch is because it needs to be a compiled EXE. I know I can run windows commands in c++ with "system(...)" however I'm not sure how to force these to be separate windows. if anyone knows a way to do that I would greatly appreciate it.
Thank you for your time
You can use CreateProcess to rum cmd,and communicate through pipe.
Your question is not clear to me, but let me try:
A single process can have no or exactly one console window. E.g. in Visual Studio, in the linker settings, you can set the subsystem to console, then the console window is opened automatically or you can use AllocConsole to get one. If you need more windows to display text, you have to create these windows by yourself (these windows aren't normal console windows). Another possibility is to start more backgroud processes, each having its own console window to display the text. To start these background processes, use CreateProcess and use for dwCreationFlags CREATE_NEW_CONSOLE.
If you have a batch file and want to display multiple console windows, use the start command to start your console program to create a new console and disply its output there, e.g.
start cmd.exe /k dir

Createprocess() for a GUI application that also writes to console

I am coding on a native app that uses CreateProcess to launch a GUI based WPF application. In the lpCommandLine parameter, I am also including the command line info along with the application name. Incidently the WPF application to launch also adds a newline to console window whenever any command line parameters are sent to it. Due to this, CreateProcess() is relaunching the application every time I close it. Any help how to solve this issue?
I also searched several links like the one below but nothing really helps to solve my issue.
Can one executable be both a console and GUI application?`

Running a terminal via QT

I am a beginner is C++. I am trying to find, is it possible to run my program in both in QT window and Linux based. When the user logins into my system, the user can select GUI or terminal mode to run the system.
Thus, I would like to know is it possible to do it. If possible how can I proceed on? What command should I use to switch from a QT window to a terminal?
Do I need to create a separate set of project for both individually or using the same set of classes?
All Linux programs (unless explicitly disabled) print out text to a terminal. If you run the program in a graphical environment you will probably not run it from a console, therefore you won't see the output, but it will be still there.
If you want your program to be usable from a console, just test whether you could create the main window and if not, fallback to simple text output.
Note that the binary will still require the X server and Qt libraries to be installed.
You can construct your application with or without the GUI enabled through the QApplication constructor. Consult the example in Qt's documentation:
http://qt-project.org/doc/qt-4.8/qapplication.html#QApplication-2
Though, it should be noted that everything in Let_Me_Be's response is correct. In fact, the Qt example does exactly what he's suggesting. Please take the time to understand his answer before you plunge into coding.

The problem of attachconsole

I need to make a windows GUI application can run in console, so I attach the console to the process when the application is invoked with a command line. However, after the application exit, the console prompt with the path doesn't show unless the ENTER key is pressed. Is there any way that the prompt with the path can directly show up without pressing the enter key? Thanks.
Short answer: This is not possible.
Long answer: Well, it is sort of possible if you are willing to relax your requirements a little bit. You basically have three options:
What you have done already. You can attach GUI application to a console but cmd.exe will not wait for your application to exit.
Create a GUI application and open console in the GUI application. The console will only last as long as you application.
Or you can restructure your application/source a bit and provide two executables, GUI one that starts GUI directly, another that is console executable.
In C#, I use SendKeys.SendWait("{ENTER}"); to do that. I think in C++, the keybd_event function does something similar.
Like Autodesk Maya with MayaBatch, you can build a small console application which basically run your GUI application with CreateProcess and wait with WaitForSingleObject.
You will have to use this "batch" version of your application in the console.

WIN32: Need Help With stdout Redirect on Hybrid Console + GUI App

I have a C++ Win32 application that runs as a console app if run with command line arguments, but as a windowed app if there are no command line arguments. I do it using this method to create a console using AllocConsole() and STD_OUTPUT_HANDLE:
http://www.halcyon.com/~ast/dload/guicon.htm
My entry point is wWinMain (unicode WinMain).
It almost works great. If I run app.exe param1, I get the console and no GUI window. If I run app.exe with no parameters, it fires up the GUI and moves merrily along with no console.
There's one thing missing.
If I run app.exe param1 > output.txt, the stdout output is not redirected to the output.txt file. It gets lost along the way. Is there a way to have a hybrid app like I have and still preserve any command-line redirects?
Try to call AttachConsole first with ATTACH_PARENT_PROCESS (value -1) as its argument. That will redirect your app to the console it has been run from, and therefore allow the > output.txt to obtain whatever it outputs. Otherwise, the output isn't caught because two different consoles are used - the one your app has been run from, and the one it has created. The redirection to the file works on the first, while your app outputs to the second.
Edit: The above is correct assuming your app is run with arguments from an existing console (cmd.exe or so). However, this might not always be the case - it might be run with arguments from a shortcut, task scheduler, another process etc. When this is the case, AttachConsole will fail, and when this happens, you should call AllocConsole as before.
I think your problem is handled by the code in this question of mine: Where do writes to stdout go when launched from a cygwin shell, no redirection
(My question is about a wierd corner case)