2021-04-21 18:58:35 +08:00
|
|
|
#include "executablerunner.h"
|
|
|
|
|
|
|
|
#include <QProcess>
|
|
|
|
#include <windows.h>
|
|
|
|
#include <QDebug>
|
2021-06-25 12:40:11 +08:00
|
|
|
#include "compilermanager.h"
|
2021-09-14 23:56:08 +08:00
|
|
|
#include "../settings.h"
|
|
|
|
#include "../systemconsts.h"
|
2021-04-21 18:58:35 +08:00
|
|
|
|
2021-11-01 09:18:23 +08:00
|
|
|
ExecutableRunner::ExecutableRunner(const QString &filename, const QString &arguments, const QString &workDir
|
|
|
|
,QObject* parent):
|
|
|
|
Runner(filename,arguments,workDir,parent),
|
2021-10-25 09:16:00 +08:00
|
|
|
mRedirectInput(false),
|
|
|
|
mStartConsole(false)
|
2021-04-21 18:58:35 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-10-25 09:16:00 +08:00
|
|
|
bool ExecutableRunner::startConsole() const
|
2021-10-24 23:13:00 +08:00
|
|
|
{
|
2021-10-25 09:16:00 +08:00
|
|
|
return mStartConsole;
|
2021-10-24 23:13:00 +08:00
|
|
|
}
|
|
|
|
|
2021-10-25 09:16:00 +08:00
|
|
|
void ExecutableRunner::setStartConsole(bool newStartConsole)
|
2021-10-24 23:13:00 +08:00
|
|
|
{
|
2021-10-25 09:16:00 +08:00
|
|
|
mStartConsole = newStartConsole;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ExecutableRunner::redirectInput() const
|
|
|
|
{
|
|
|
|
return mRedirectInput;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExecutableRunner::setRedirectInput(bool isRedirect)
|
|
|
|
{
|
|
|
|
mRedirectInput = isRedirect;
|
2021-10-24 23:13:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const QString &ExecutableRunner::redirectInputFilename() const
|
|
|
|
{
|
|
|
|
return mRedirectInputFilename;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExecutableRunner::setRedirectInputFilename(const QString &newDataFile)
|
|
|
|
{
|
|
|
|
mRedirectInputFilename = newDataFile;
|
|
|
|
}
|
|
|
|
|
2021-04-21 18:58:35 +08:00
|
|
|
void ExecutableRunner::run()
|
|
|
|
{
|
|
|
|
emit started();
|
2021-11-01 09:18:23 +08:00
|
|
|
auto action = finally([this]{
|
|
|
|
emit terminated();
|
|
|
|
});
|
2021-04-21 18:58:35 +08:00
|
|
|
QProcess process;
|
|
|
|
mStop = false;
|
2021-06-25 12:40:11 +08:00
|
|
|
bool errorOccurred = false;
|
|
|
|
|
2021-04-21 18:58:35 +08:00
|
|
|
process.setProgram(mFilename);
|
|
|
|
process.setArguments(QProcess::splitCommand(mArguments));
|
|
|
|
process.setWorkingDirectory(mWorkDir);
|
2021-09-14 23:56:08 +08:00
|
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
|
|
QString path = env.value("PATH");
|
|
|
|
QStringList pathAdded;
|
|
|
|
if (pSettings->compilerSets().defaultSet()) {
|
|
|
|
foreach(const QString& dir, pSettings->compilerSets().defaultSet()->binDirs()) {
|
|
|
|
pathAdded.append(dir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pathAdded.append(pSettings->dirs().app());
|
|
|
|
if (!path.isEmpty()) {
|
|
|
|
path+= PATH_SEPARATOR + pathAdded.join(PATH_SEPARATOR);
|
|
|
|
} else {
|
|
|
|
path = pathAdded.join(PATH_SEPARATOR);
|
|
|
|
}
|
|
|
|
env.insert("PATH",path);
|
|
|
|
process.setProcessEnvironment(env);
|
2021-10-25 09:16:00 +08:00
|
|
|
process.setCreateProcessArgumentsModifier([this](QProcess::CreateProcessArguments * args){
|
|
|
|
if (mStartConsole) {
|
2021-10-24 23:13:00 +08:00
|
|
|
args->flags |= CREATE_NEW_CONSOLE;
|
2021-10-25 09:16:00 +08:00
|
|
|
}
|
|
|
|
if (!mRedirectInput) {
|
2021-10-24 23:13:00 +08:00
|
|
|
args->startupInfo -> dwFlags &= ~STARTF_USESTDHANDLES;
|
2021-10-25 09:16:00 +08:00
|
|
|
}
|
|
|
|
});
|
2021-06-25 12:40:11 +08:00
|
|
|
process.connect(&process, &QProcess::errorOccurred,
|
|
|
|
[&](){
|
|
|
|
errorOccurred= true;
|
|
|
|
});
|
|
|
|
// qDebug() << mFilename;
|
|
|
|
// qDebug() << QProcess::splitCommand(mArguments);
|
2021-10-25 09:16:00 +08:00
|
|
|
if (!redirectInput()) {
|
2021-10-24 23:13:00 +08:00
|
|
|
process.closeWriteChannel();
|
|
|
|
}
|
2021-04-21 18:58:35 +08:00
|
|
|
process.start();
|
|
|
|
process.waitForStarted(5000);
|
2021-10-25 09:16:00 +08:00
|
|
|
if (process.state()==QProcess::Running && redirectInput()) {
|
2021-10-24 23:13:00 +08:00
|
|
|
process.write(ReadFileToByteArray(redirectInputFilename()));
|
|
|
|
process.closeWriteChannel();
|
|
|
|
}
|
2021-04-21 18:58:35 +08:00
|
|
|
while (true) {
|
|
|
|
process.waitForFinished(1000);
|
|
|
|
if (process.state()!=QProcess::Running) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (mStop) {
|
2021-08-01 23:24:37 +08:00
|
|
|
process.closeReadChannel(QProcess::StandardOutput);
|
|
|
|
process.closeReadChannel(QProcess::StandardError);
|
|
|
|
process.closeWriteChannel();
|
2021-06-25 12:40:11 +08:00
|
|
|
process.terminate();
|
2021-08-01 23:24:37 +08:00
|
|
|
process.kill();
|
|
|
|
break;
|
2021-06-25 12:40:11 +08:00
|
|
|
}
|
|
|
|
if (errorOccurred)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (errorOccurred) {
|
2021-09-19 17:59:03 +08:00
|
|
|
//qDebug()<<"process error:"<<process.error();
|
2021-06-25 12:40:11 +08:00
|
|
|
switch (process.error()) {
|
|
|
|
case QProcess::FailedToStart:
|
2021-09-04 19:37:33 +08:00
|
|
|
emit runErrorOccurred(tr("The runner process '%1' failed to start.").arg(mFilename));
|
2021-06-25 12:40:11 +08:00
|
|
|
break;
|
2021-09-04 19:37:33 +08:00
|
|
|
// case QProcess::Crashed:
|
|
|
|
// if (!mStop)
|
|
|
|
// emit runErrorOccurred(tr("The runner process crashed after starting successfully."));
|
|
|
|
// break;
|
2021-06-25 12:40:11 +08:00
|
|
|
case QProcess::Timedout:
|
|
|
|
emit runErrorOccurred(tr("The last waitFor...() function timed out."));
|
|
|
|
break;
|
|
|
|
case QProcess::WriteError:
|
|
|
|
emit runErrorOccurred(tr("An error occurred when attempting to write to the runner process."));
|
|
|
|
break;
|
|
|
|
case QProcess::ReadError:
|
|
|
|
emit runErrorOccurred(tr("An error occurred when attempting to read from the runner process."));
|
2021-04-21 18:58:35 +08:00
|
|
|
break;
|
2021-10-20 18:05:43 +08:00
|
|
|
default:
|
|
|
|
break;
|
2021-04-21 18:58:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|