I want to compile a c++ file from Qt application by using QProcess. But it is not working, I don't see any .o or .exe file generated by the compiler.
Here is what I am doing -
QProcess *process = new QProcess(this);
QString program = "g++";
QStringList arguments;
//fileName is fetched from QFileDialog
arguments << fileName << "-o" << QFileInfo(fileName).path() + QFileInfo(fileName).baseName() + ".exe";
errorFilename = QFileInfo(fileName).baseName() + "_error.txt";
process->setStandardOutputFile(errorFilename);
connect(process, SIGNAL(finished(int)), this, SLOT(compiled()));
process->start(program, arguments);
Pleae tell me what's wrong with this code. I am working on windows 7.
Keep in mind that errors don't go to stdout, they go to stderr. Try using:
process->setStandardErrorFile(errorFilename);
Also QFileInfo::path() won't have a path separator at the end, so you'll need to add one when concatenating the path with the base filename:
QFileInfo finfo(fileName);
arguments << fileName << "-o" << QFileInfo( QDir(finfo.path()), finfo.baseName() + ".exe").filePath();
Related
I have two programs each with QProcess and I have a different behavior concerning the QProcess input with accentuated characters
(more precisely I create a Qprocess to execute a dos copy command and the path takes accent).
The environnement of execution and development is Windows 10.
The first program is a simple prototype that I made to test if my code can work correctly.
Here is the prototype code I have, in which the copy works correctly, integrated in a simple main() function.
The code is supposed to copy a file named sfx.exe into a path with accent F:\path_accentué and it indeed does the copy correctly.
#include <QCoreApplication>
#include <Qdebug>
#include <QObject>
#include <QProcess>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QProcess* processus = new QProcess();
QStringList args;
QString path("F:\\path_accentué");
args << "/C" << "copy" << "E:\\test\\sfx.exe" << path;
processus->start("cmd.exe", args);
if (!processus->waitForStarted())
{
qDebug() << "Could not launch the process";
}
//processus->write(s.c_str());
if (!processus->waitForFinished(-1))
{
qDebug() << "Finished";
}
delete processus;
return app.exec();
}
However, when I integrate (literally copies and pasted without changing) this prototype within a bigger code project, my instance of QProcess does not recognize the accentuated path, as if accents are no more supported.
This is the part that I copy/paste in the bigger project and which I now execute via a button click in QT.
And this time, the QProcess doesn't recognize the accentuated path (Instead it creates a file with name like this path_accentu�)
QProcess* processus = new QProcess();
QStringList args;
QString path("F:\\path_accentué");
args << "/C" << "copy" << "E:\\test\\sfx.exe" << path; processus->start("cmd.exe", args);
if (!processus->waitForStarted())
{
qDebug() << "Could not launch the process";
}
//processus->write(s.c_str());
if (!processus->waitForFinished(-1))
{
qDebug() << "Finished";
}
I do not find in the documentation a way to force the QProcess to recognize accentuated inputs.
I would like to understand why the QProcess instance behaves differently when integrated within my bigger project.
What may impact the behavior of the QProcess and leads it to treat differently the input in the second case?
Note:
The QProcess is needed for more things but not only for the copy (such as getting feedback and percentage of operations). The copy is only to isolate the problem. In reality, I do much more things.
I tried to recreate your behaviour with Qt 5.15 and could create a file with accent with
start("cmd",{args...})
start("cmd /c args...")
setNativeArguments("/c args...") + start("cmd")
Last one is recommended for "cmd" calls, see the remarks here:
https://doc.qt.io/qt-5/qprocess.html#start
The only thing, which did not work, because it deadlocks was
setArguments({args...}) + start("cmd")
Demo here:
https://gist.github.com/elsamuko/59f110cf3a678beae9db27860f6305c9
I've created two programs in Qt.
Program A - Console project with interactions in shell
Program B - GUI project
Now I want to start Program A from Program B. For that purpose I tried many things and ended with:
QProcess *process = new QProcess(this);
QString command = "cmd.exe";
QStringList arguments;
arguments << "/C" << settings.getPath().replace("/","\\");
process->start(command, arguments);
This starts a process, but doesn't open a cmd in Windows.
I also tried out:
QProcess *process = new QProcess(this);
QString command = "start";
QStringList arguments;
arguments << "cmd.exe" << "/C" << settings.getPath().replace("/","\\");
process->start(command, arguments);
It looks like the process is started in the background. In that case I am unable to use my command line program.
How can I start an interactive cmd?
Which devenv are you using for each of the projects?
Depending on the dev-env you are using, you could try setting up your console project to run in a cmd.exe which is not in the background (you would need to look at the manual from your dev-env in this case)
Other thing:
Can you start your (compiled) console project via
system("projecta.exe"); ?
from project b?
If you are using Visual Studio compiler, take a look at this : QProcess with 'cmd' command does not result in command-line window
Which uses following code (note the CREATE_NEW_CONSOLE flag):
#include <QProcess>
#include <QString>
#include <QStringList>
#include "Windows.h"
class QDetachableProcess
: public QProcess {
public:
QDetachableProcess(QObject *parent = 0)
: QProcess(parent) {
}
void detach() {
waitForStarted();
setProcessState(QProcess::NotRunning);
}
};
int main(int argc, char *argv[]) {
QDetachableProcess process;
QString program = "cmd.exe";
QStringList arguments = QStringList() << "/K" << "python.exe";
process.setCreateProcessArgumentsModifier(
[](QProcess::CreateProcessArguments *args) {
args->flags |= CREATE_NEW_CONSOLE;
args->startupInfo->dwFlags &=~ STARTF_USESTDHANDLES;
});
process.start(program, arguments);
process.detach();
return 0;
}
I am trying to run iBooks from my QT application.
I tried both QProcess::execute() and QProcess::start(), but none of them worked. Here is my code:
QString program ="/Users/muhammed/Applications/iBooks.dmg";
QStringList arguments;
QProcess *q=new QProcess(this);
q->start(program,(QStringList) arguments<<"/Users/muhammed/Applications/iBooks.dmg");
Nothing happens when i use this. Thanks in advance.
You cannot run a .dmg file directly. You need to pass the .dmg file path to open command like this:
$ open application.dmg
So, your Qt code would look like this with QProcess::execute static method:
QProcess::execute( "open", { "your-dmg-file-path-here" } );
Or,
const QString dmgPathArg { "your-dmg-file-path-here" };
QProcess process {};
process.start( "open", { dmgPathArg } );
if ( !process.waitForFinished( -1 ) )
{
qDebug() << process.readAllStandardError();
return;
}
qDebug() << process.readAllStandardOutput();
Actually, there'll be some error string that you can see using the readAllStandardError() and readAllStandardOutput() methods.
Take a look at the documentation of QProcess. It has some pretty good examples to start with.
Hope that helps.
I am using Qt4.8, What I want is open a pdf and print that pdf automatically through cmd.exe, without clicking on print button in pdf reader by using QProcess:
I have two different code that do two different task:
Opne Pdf
QString scmd= "cmd.exe";
list.push_back("/C");
list.push_back("test.pdf");
Process.start(scmd, list);
Sleep(2000);
Print pdf without open it
QString scmd2 = "C:/Program Files (x86)/Adobe/Reader 11.0/Reader/AcroRd32.exe.exe"
list2.push_back("/t");
list2.push_back("test.pdf");
Process.start(scmd2, list2);
Sleep(2000);
So I want to merge this command, I dont know how I can do that? Please suggest me something
You can fetch all information from HKEY_CLASSES_ROOT of windows registry.
Here is a example how to fetch default path to printing software and how to run it. I tested it on Qt 5.7
#include <QSettings>
#include <QProcess>
#include <QDebug>
int main(int argc, char *argv[])
{
const QString classesRoot = "HKEY_CLASSES_ROOT";
// get ID of .pdf extension
QSettings pdfSettings(classesRoot + "\\.pdf", QSettings::NativeFormat);
QString pdfId = pdfSettings.value("Default").toString();
// get path to default program that associated with PDF files
QString printPath = QSettings(classesRoot + "\\" + pdfId + "\\shell\\print\\command", QSettings::NativeFormat).value("Default").toString();
QString openPath = QSettings(classesRoot + "\\" + pdfId + "\\shell\\open\\command", QSettings::NativeFormat).value("Default").toString();
qDebug() << "print path" << printPath;
qDebug() << "open path" << openPath;
// open .pdf file
QProcess::startDetached(openPath.arg("full path to pdf file.pdf") );
// print .pdf file
QProcess printProcess;
printProcess.start(printPath.arg("full path to pdf file.pdf") );
printProcess.waitForFinished(-1);
return 0;
}
I compiled a c++ source file from the Qt app I am creating. Now I want to run the exe file generated and also to redirect its input and output to txt files. But when I try to run it from QProcess, it fails to execute with exit code -2.
This is how I compiled the file using QProcess -
arguments << fileName << "-o" << exeFileName << "-static";
connect(compileProcess, SIGNAL(finished(int)), this, SLOT(compiled()));
compileProcess->start(QString("g++"), arguments);
And this is how I run the exe from QProcess in the slot compiled() -
runProcess->setStandardInputFile(inputFilename);
runProcess->setStandardOutputFile(QFileInfo(exeFileName).path() + "/output.txt");
int code = runProcess->execute(exeFileName); //code = -2
The program runs fine when I start it manually. So, why can't it be started from QProcess?
I am working with Qt 5.0.2 on Windows 7
This is the source file I am compiling -
#include <iostream>
int main() {
std::string s;s
std::cin >> s;
std::cout << s;
return 0;
}
I finally got it to work. The exe file path had spaces in it and Qt did not implicitly add quotes around it. Adding quotes explicitly did the job.
runProcess->start("\"" + exeFileName + "\"");