QProcess doesn't show the command window - c++

I have the following code which runs an exectuable using QProcess. The code all runs fine and the new executable runs and is all fine.
QString fileName = ui.textBrowser_csvFile->toPlainText();
QString tableName = ui.textBrowser_2->toPlainText();
QString program = "resources/myExe.exe";
QStringList arguments;
arguments << tableName << fileName;
bool res = QProcess::startDetached(program, arguments);
It is a Qt Console Application using QCoreApplication and there it doesn't spawn the terminal window like it would if I run it normally. It would be useful to monitor the progress of the executable so how do I get my Application to run the new program and display the terminal window?
Edit Possible duplicate does technically answer the question, but I have answered this question with a working solution.

So as discussed in the comments on my questions this StackOverflow post explains that this is infact correct behaviour when using the startDetached() function.
I'm not entirely sure what the answer to that question was suggesting to do but here is my working solution.
system() is a windows specific function which "can execute any command that can run on terminal if operating system allows" link
If I replace this line:
bool res = QProcess::startDetached(program, arguments);
with the following, then it works:
system(QString("D:\\Qt\\5.9.1\\msvc2017_64\\bin\\myApp.exe " +tableName +" " + fileName).toStdString().c_str());
In the short term I have simply moved this application into the Qt folder because it needs the DLLs however with a proper release of this app you can run it from wherever, including from next to the application that is running it.
I do then get a terminal window and my app runns correctly.

When migrating from Qt 5.7.0.0(x86) to 5.10.0.0(x64) I was really surprised to see that using the new Qt version, a child (launched with "QProcess::startDetached") process will not show up it's console (even though it's a console application! (SubSystem:CONSOLE))
MS documentation regarding "AllocConsole" says:
Console applications are initialized with a console, unless they are
created as detached processes (by calling the CreateProcess function
with the DETACHED_PROCESS flag).
https://learn.microsoft.com/en-us/windows/console/allocconsole
Console processes are not attached to a console if they are created
using CreateProcess with DETACHED_PROCESS
https://learn.microsoft.com/en-us/windows/console/creation-of-a-console
So I'm assuming that new Qt versions are using the "CreateProcess" with the "DETACHED_PROCESS" flag.
What I've ended up doing:
For child process I'm now using "SubSystem:WINDOWS". (Really
important)
Inside the child process I'm creating the new console by using "AllocConsole()"
Using: "freopen("CONOUT$", "w", stderr);" and "freopen("CONOUT$",
"w", stdout);" ("stderr" is really important if you want to capture qDebug, qInfo, etc...)
P.s.
If you would need to use "SubSystem:CONSOLE", be sure to call "FreeConsole" before calling "AllocConsole". This is required, because child process will by default be using parent process console...

Related

QProcess with CreateNoWindow

In C# there is an attribute which enables application to run 3rd party apps without showing the app window.
Is there any way to run a console application without showing the console window in QT without using Win32 CreateProcess function?
QProcess.start() will run the console application without showing its window, but you may also wish to have some control over it. Please see this example:
QProcess p;
p.setProcessChannelMode(QProcess::MergedChannels);
p.setStandardOutputFile("out.txt");
p.start("cmd.exe", QStringList()<<"/C"<<"ping"<<"127.0.0.1");
p.waitForStarted();
p.waitForFinished();
You can pass commands and parameters to the console using second argument in the start method (inside QStringList). It is also possible to redirect the output to some file, with setStandardOutputFile method.
If you need to show the window, use p.startDetached().

starting another program with arguments from qt app

I have a simple app
int main(int argc, char* argv[]){
//cout << argv[1];
cout << "hello world";
getchar();
}
and I want to start it from qt program using
QProcess *process= new QProcess(this);
QString appPath= "..../.../TestApp2.exe";
process->start(appPath);
the problem is that my program dosen't starts, even without arguments. I have tried to start a standard app like "calc" and it worked. How could I start my app with specific args (sure after uncommitting the second line of the first snippet)
I have tried to start a standard app like "calc" and it worked. How could I start my app
Your application is a console application.
QProcess hides the console window for console applications and redirects their STDOUT/STDERR for you to read them (using readAllStandardOutput(), readAllStandardError(), ...). and whatever you write() to your QProcess goes to its STDIN. So, if you are expecting to see a console window when the process starts, you are wrong.
If you want to start a console application without hiding its console window, you can use QProcess::startDetached():
QProcess::startDetached("test.exe");
But most of the times there is no reason to do so. QProcess is meant to be used from a GUI application in order to start a process behind the scenes, and take a result from it. After that, you can display the result to the user the way you like. A user of a GUI application usually doesn't expect a console window asking him/her for input every now and then. Also, He/She wouldn't expect to see the result in a console window.

Qt GUI application with console output - hide console on normal startup on Windows

If I open my application an empty console window appears, since I added CONFIG += console to my .pro file. I need the console, because I've implemented a CLI, where some stuff needs to get printed out on the console. On Linux and Mac OSX, I don't actually need the CONFIG += console there. It just works.
How can I prevent opening a windows console, if the .exe gets executed normally over a double click, but display some outputs if my .exe gets started via a console window?
Basically, I use qDebug() << "myText"; and then after that I exit the application with return 0;.
Unfortunately, Windows is somewhat deficient in this area. A console application will always open up a console, even if you don't want it. You can close it right away, but it still looks bad.
Your application must be a non-console application. On startup, check if you have access to a console, as you would when launched from cmd.exe. Then access cmd's console and inject your output into it.
See my question about this for details.
It is a GUI application? AFAIK it is not possible (or at least not trivial) writing a mixed Qt application that can act as both, a desktop (GUI) application and a console (CLI) application.
I am not sure what you intend to do. If you really need a console variant, try to build two different applications based on the same sources (one console build and one GUI build).
If you only need a GUI application that is able to print out some information, remove the console code and write the output into a file instead.
I think here is an answer for you question: https://stackoverflow.com/a/3370017/1091536
You need console application, than launch your GUI application and prints it's output.
The application for launch your GUI application you can find here https://github.com/gomons/AppDebugLauncher
It's worth noting that under some circumstances the console window won't briefly appear. For example if you run in gui mode via a shortcut with Run set to Minimized: the console window won't appear. Then, in your code, you can restore the size of the gui window. Its a bit of a nasty workaround but masks the behaviour from the user that bit more.
If you're program is going to be installed and usually started via shortcut, then its maybe its an option.

Win32 application with console output and without new window

I'd like to create a tool that can either act as command line (display some console output based on input parameters), or display a window, based on input parameters.
I'm using MSV2012 with C++, and it seems you have to 'choose' between console and window app.
I know the net is filled with samples which use AllocConsole() and redirect std::out, but it doesn't make it feel like a command line application : calling the exe from the windows console will open a new window with the console output...
Is there a way to have it use the current console window instead of allocating a new one?
If not possible, I'll make 2 applications instead, but that's a pity..
Someone else may have a more authoritative answer, but I don't believe it's supported.
The usual workaround is to create a Windows app, but have a command-line wrapper that launches it from the CLI (and provides a channel for communicating with the original console).
It's not technically supported but I found a good solution by getting a snapshot for the current process, finding the parent process, attaching to it's console if it's a console app or creating one with AllocConsole, redirecting the output, getting the thread of the parent process if it's cmd.exe and suspending it, resuming it just before I exit my app

How can I hide the command prompt of an application after it has started?

How do I go about suppressing the command prompt of a c++ application using the mingw compiler AFTER the program has started.. -mwindows works great in the linker settings but I want to be able to toggle it whilst the program is running, is this possible at all?
I am using a text editor and command line so no IDE related answers please.
As far as I know: no, at least not with a single executable. When you open an application in a Windows based console, it will start an instance of conhost.exe in order to provide an environment to your command line application. The console host will run as long as your applications hasn't exited.
It's hard to determine in which circumstances you'll need this behavior. But you could create two application - one which is a simple command line application, and one which has been compiled with -mwindows. The latter could call the first. After the first has exited the second will continue executing.
Note that this will leave the user bewildered, as it seems to him your application has stopped (as the console window has been closed) and a -mwindow compiled application doesn't create any GUI elements.
You can use WinAPI function ShowWindow to hide and show any window. There is a quirk, however - this function accepts an HWND handle as its argument and there is no obviuos way to obtain console HWND. Following is pretty convoluted way to get it:
HWND GetConsoleHwnd(void)
{
#define MY_BUFSIZE 1024 // Buffer size for console window titles.
HWND hwndFound; // This is what is returned to the caller.
TCHAR pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated
// WindowTitle.
TCHAR pszOldWindowTitle[MY_BUFSIZE]; // Contains original
// WindowTitle.
// Fetch current window title.
GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);
// Format a "unique" NewWindowTitle.
TCHAR * format=_TEXT("%d/%d");
wsprintf(pszNewWindowTitle,format,
GetTickCount(),
GetCurrentProcessId());
// Change current window title.
SetConsoleTitle(pszNewWindowTitle);
// Ensure window title has been updated.
Sleep(40);
// Look for NewWindowTitle.
hwndFound=FindWindow(NULL, pszNewWindowTitle);
// Restore original window title.
SetConsoleTitle(pszOldWindowTitle);
return(hwndFound);
}
Forgive me for this dirty trick, but it works perfectly in my code and is an official way of getting console HWND.
Some programs have to be of a console type. Like Emacs where the same executable can be launched to operate in console (with -nw option) and in GUI.
To hide that console there are lots of methods (including esoteric WSH scripts, or 3rd party utils, like nircmd exec hide notepad.exe) but there is a simple modern portable way:
powershell -c Start-Process -WindowStyle Hidden -FilePath notepad.exe
You can wrap that ugly command into .bat script alias.
PS Use Task Manager to kill hidden Notepad ))