Is it possible to embed system command line right inside your application window?
I want to be able to have the command line take some space on the bottom of my C++ application, and my application to take the above space. Ideally it should work on Mac, Linux and Windows, but for starters Windows is the primary goal as I am developing on it.
Speaking for Windows, the Windows console window is "special" in that it gets special treatment, different than any other window on the system. You will not succeed in manipulating it for your own use. For a good example, try using Spy++ on a console window.
Note that the window created with AllocConsole is not a command-line interpreter, it's just a console window.
You should implement your own console window, and as far as interpreting the commands I can think of a few options to explore depending on what you expect, behavior-wise and complexity-wise:
Delegate commands to a hidden cmd.exe
Interpret commands yourself
There are probably open-source solutions for command line interpreting.
In Windows, you can do that using some WinAPI functions like ShellExecute and CreateProcess (there are a few others that I don't remember). You get the command string from your GUI, pass it to one of these WinAPI functions, then send the output back to your GUI.
You want to do this on multiple platforms, so I would suggest making a generic module (class or namespace of functions, whatever fits you best) that allows using the OS terminal agnostic of the actual underling OS. Then. when you want to port your app to another OS, you just change the implementation of this module.
Note: Boost has (had?) a library under development that made running shell commands easier, Boost.Process. But it's currently on version 0.4 and hasn't been updated since October 4, 2010 (even though its status is still "on going").
Related
I have seen windows applications that operate with both a Window and a console. I find myself wondering about this every now and then and I remember whenever I do research it I never find a solution.
Is there a way to program my WinApi C++ application such that I can output to the console as I would normally do when under the linker option SUBSYSTEM:CONSOLE? In other words I can have a Window open, with my WinMain and WndProc etc. but I would also like to do std::cout, std::cin and std::wcout.. A good use-case for that, would be to use the console for logging stuff and the Window as the main application.
Would It be a good idea to use std::system() instead and launch cmd from that and then output? I don't think so, but of course I don't know.
Windows 8.1, x86_64, MSVS 2017.
Use AttachConsole to attach to an existing console, or AllocConsole to create a new console. Then redirect cin/cout to that console as needed (depending on the requirements of your compiler's particular runtime implementation). Or, just use ReadConsole/WriteConsole instead.
Yes, set the subsystem to WINDOWS and /ENTRY (entry point) to WinMainCRTStartup (or wWinMainCRTStartup if you're using unicode). You can even set it only for the Debug configuration, so the console won't appear for the Release.
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");
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.
Are there winAPI function (without classes) to create a daughter window from console application. It necessary to print graphics of shapes on window, and input commands to console.
Thank you.
it's simpler to create console window for your GUI application. Have a look here
I'm not sure if you mean something specific by "daughter", but it's certainly possible for a console application to create a window (or as many as it likes). It's also possible for a windowed application to allocate a console.
Allocating a console from a windowed program is theoretically a bit work, but does have one advantage: you can write the majority of your windowing "stuff" using an application framework of your choice (Qt, wxWidgets, etc.)
If you work directly with the Windows API, it's a bit easier to create a console application and create windows as you see fit. About all you have to do in this case is write your code just as you normally would a windowed program, but instead of WinMain, name your entry function main. Based on that, the linker will automatically set the "console" flag in the executable, and Windows will give it a console when it starts up. The big advantage here is that C++ standard library gets initialized automatically, so things like cin all work without any extra effort on your part. If you start from a Windowed program and allocate a console, all that'll work by default will be the Windows API functions (ReadConsoleInput, WriteConsoleOutput, ReadFile, WriteFile, etc.) You can get the C and C++ functions to work, but you have to deal with some fairly poorly documented areas (that are all open to change with the next release of the compiler) to make it happen. I'd generally avoid this unless I was only going to use the Windows API functions to deal with the console anyway.
Here is a much easier way that may work well for you, provided you're using Visual Studio:
If you are, you can start a forms application by creating a forms project, add the necessary forms, and then change the application type (by right-clicking the project and selecting properties) and changing it to a console application. It will still spawn the form windows as you would expect, but will also start a Console window (which will still be populated by cout, etc...)!
I want to hide my console of C when I run my application. How can I make my application run in the background?
Programs with main() by default are compiled as SUBSYSTEM:CONSOLE applications and get a console window. If you own the other processes your application is starting, you could modify them to be windowed applications by one of the following methods:
Modify them to use WinMain() instead of main(). This is the typical approach but requires modifying code. (If the reason for using main() is for easy access to argc/argv, MSVC provides global __argc/__argv equivalents for windowed applications.)
Explicitly specifying the subsystem and entry point via /SUBSYSTEM:WINDOWS /ENTRY:main arguments to link.exe.
Use editbin.exe (from the Windows SDK) to change the subsystem type after the fact. This one might be useful if you don't have source code access to the spawned processes.
The easiest way to do this is to use a Windows Forms project rather than Console and then hide the startup form. The other option of course is a Windows Service, but this might be overkill ...
Use CreateProcess with the DETACH_PROCESS flag.
If I remember correctly, there's no way to do it programmatically. There are options to do it. I think I have done it in the past by creating a Windows project, but having no Windows Forms code (I am just including the files from my console application). No console window popped up. I believe I did it in Code::Blocks once by changing an option in the GUI. I am sorry I can't be specific, but I am using Visual Studio 2010 RC and the way I do it there may not be the same as yours.
Your comment makes me think that you're spawning processes. You do it by the function you call. I don't know what language you're using (I'll assume C, because you said you're launching a C application you created?), but there is either a flag to say hide the window or (or a flag you don't set to not show it) or use an alternative function which does the same thing, but launches the process a different way. Try shellexecute and system().