starting another program with arguments from qt app - c++

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.

Related

QtCreator: What is the best way to print strings to the terminal?

I am learning to use Qtcreator on lubuntu 17.10, and want to print some output to the terminal. I've had trouble, so have stripped my program down to a basic Hello World to print a single string to the terminal. Currently, I am using this code:
#include <QCoreApplication>
#include <iostream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::cout << "HELLO WORLD" << std::endl;
return a.exec();
}
My .pro file contains these lines which look like they could influence the terminal behaviour:
QT -= gui
CONFIG += c++11 console
I also have 'Run in terminal' checked in the Run Settings.
This builds without issue. When I run it, the terminal pops up(I am using terminator), and is blank, with a blinking cursor. To get the string to appear, I have to press <Enter>. The string appears, but the program doesn't end. I don't get the "Press enter to close the window" type message in the terminal that would indicate the program has ended, and I must close the terminal 'manually'. Also, in the Application Output window, it says:
/home/user/path_to_my_program crashed.
Presumably because I force close the terminal. I would really like to figure out why it's not printing the string to terminal and exiting cleanly.
The terminal after I press ENTER(blank beforehand):
This is normal for a Qt console Application. It is running a messageloop and exactly doing what it should.
To send text to the console you can use std::cout, qout or qDebug(). The latter is used for debugging. More information can be found here. It also contains the pittfalls you run into. Qt console Application

QProcess doesn't show the command window

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...

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().

How to wrap a command line tool into an app and properly quit it?

I have a multi-threaded command-line program in C++. When launched from the terminal, I can properly quit with q <RET>, which will call a series of clean_up routines which will eventually release all resources. Note that if q <RET> is never pressed the program just loops forever. Note also that the program launches some GUI Windows on its own.
I need to wrap this tool as an app - nothing really fancy, just a nice icon with all the necessary assets inside it so that simple users can launch it simply by double-clicking. I've used Platypus with success to make such an app in the past.
However I can't find a way to properly quit the program. There is no way to std::cin in my program from there and I reckon that on quit (from the menu or cmd-Q) platypus just sends a SIGTERM or something similar to my program (I can't really use this to properly clean my application - I need to end the infinite loop on main and have all destructors called implicitly when leaving main).
Isn't there any other easy way to wrap my program as an .app, but in a way that I can call a particular function on quit? I thought of creating a dummy app with Cocoa/Swift, make my program a static lib and call it from there, but there has to be a simpler way.
I'd wrap it with an application that uses the Qt Framework, which also uses C++.
Using QProcess to launch the program, the documentation states: -
The QProcess class is used to start external programs and to communicate with them
Here's a simple example of what you can do...
#include <QApplication>
int main(int argc, char *argv[])
{
// Main application class
// Use QCoreApplication instead, if this is not a GUI app
QApplication app(argc, argv);
// launch the process with the given arguments
QProcess *myProcess = new QProcess(parent);
myProcess->start(program, arguments);
if (!myProcess.waitForStarted())
return -1;
// quit the app as soon as it has started, but
// just for demonstration purposes
myProcess.write("q");
return app.exec(); // starts the event loop
}
You can build a handler for SIGTERM in your app.
Here's a program I wrote that does this, but in C it's a common practice to bind signals to handlers with the "signal" function. Given that you're using C++, you can use C with it directly, or find the equivalent thing in C++ (of which there surely is an identical construct). The key thing is to use the signal function to bind signal with handler.
https://github.com/jpnorair/otter/blob/master/main/main.c

QProcess STDIN with show console

I want to create a process under QProcess with console show and acccess STDIN and STDOUT streams.
my code:
QProcess *p1 = new QProcess(this);
p1->start("cmd.exe");
if I want to show console I must use startDeatached() function, but by using this, I lost my STDIN/OUT access in my program.
if I want to have access these, I dont have my console show!!!???
help me tanx.
after more investigations, I did not find my exact answer. But I did a quick trick (kalak rashti) for this problem.
I used a QTextEdit custom class to simulate some thing behaves like console. frome this link:
https://code.google.com/p/qterminalwidget/source/browse/trunk/
with some changes for my purpose.