运行自定义可执行文件,QProcess 立即退出,退出代码为 1

Posted

技术标签:

【中文标题】运行自定义可执行文件,QProcess 立即退出,退出代码为 1【英文标题】:Run custom executable with QProcess exiting immediately with exit code 1 【发布时间】:2019-10-23 12:20:54 【问题描述】:

我需要在我的应用程序中运行自定义可执行文件。我有以下代码来运行我的进程:

QFileInfo fiUpdator(updatorLocation);
if(!fiUpdator.isExecutable()) 
    qWarning() << "Maintenance Tool is not an executable";
    return;


qDebug() << "Starting updator app";
QString pid = QString::number(qApp->applicationPid());
QString appName = qApp->applicationName();

QProcess *p = new QProcess;

connect(p, &QProcess::started, this, [this]()
    qDebug() << "Updator Process Started";
);

connect(p, &QProcess::errorOccurred, this, [this](QProcess::ProcessError error)
    qDebug() << "Error Occurred : " << error;
);

connect(p, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this, p]()
    qDebug() << "Finished Updator Process";
    QString str("Exit [" + QString::number(p->exitCode()) + "] " + p->exitStatus());
    qDebug() << str;
);

connect(p, &QProcess::readyReadStandardError, this, [this, p]()
    QByteArray ba = p->readAllStandardError();
    qDebug() << "Error:\n" << QString::fromUtf8(ba);
);

connect(p, &QProcess::readyReadStandardOutput, this, [this, p]()
    QByteArray ba = p->readAllStandardOutput();
    qDebug() << "Output:\n" << QString::fromUtf8(ba);
);

connect(p, &QProcess::stateChanged, this, [this](QProcess::ProcessState newState)
    qDebug() << "State Changed : " << newState;
);

p->start(
            updatorLocation,
            QStringList()
                << pid
                << appName
                << newFilePath
                << oldFilePath);

应用程序(一个 qt 控制台应用程序)按预期运行,使用

start "" "C:\Path\To\AwesomeConsoleApp.exe" 

它会短暂打开一个带有编码输出的新 CMD 窗口,或者打开 cmd.exe 并运行

C:\Path\To\AwesomeConsoleApp.exe

在同一 cmd 窗口中将输出显示到 stdout

进程信号触发如下:

    stateChanged Starting stateChanged Running QProcess::started stateChanged NotRunning QProcess::finished:输出Exit[1] 0

我尝试用C:\Windows\System32\calc.exe 替换.exe 来启动,它启动时没有问题。

这是否意味着我的自定义可执行文件有问题?

【问题讨论】:

QProcess::ExitStatus 0 表示进程正常退出。可能是可执行文件对带有退出代码 1 的参数做出反应。尝试打印所有参数并手动运行它们。 @uni 已解决,请参阅发布的答案。 【参考方案1】:

想删除这个问题,但如果它可能有用,我会发布一个答案,将来可能会对某人有所帮助。

问题不在于调用应用程序代码或被调用应用程序的代码(即如上所示的MaintenanceTool)。相反,这是MaintenanceTool 权限的问题。

所以,我的MaintenanceTool 需要管理权限 才能执行。我的调用应用程序不以管理权限运行,但我的MaintenanceTool 可以。为此,我使用QProcess 来帮助启动MaintenanceTool 应用程序。

注意:为了获得管理权限,我使用this 作为我的工作的灵感。

我尝试了以下与 QProcess 的组合,请注意,这些都不适用于以管理员身份运行应用程序

QProcess::startDeteched("cmd.exe", QStringList() << "/C" << "/path/to/mtool.exe -arg1 -arg2");

QProcess::startDeteched("cmd.exe", QStringList() << "/C" << "/path/to/mtool.exe -arg1 -arg2");

QProcess::startDeteched("start.exe", QStringList() << "" << "/path/to/mtool.exe -arg1 -arg2");

QProcess::startDeteched("C:\Windows\System32\cmd.exe", QStringList() << "/C" << "/path/to/mtool.exe -arg1 -arg2");

QProcess::startDeteched("C:\Windows\System32\cmd.exe", QStringList() << "/C" << "/path/to/mtool.exe -arg1 -arg2");

QProcess::startDeteched("/path/to/mtool.exe", QStringList() << "" << "-arg1" << "-arg2");

我还创建了QProcess *p,添加了readStandardOutput() 等(如问题所示),提供Exit Code 0。此外,我还尝试将所有命令打印到应用程序,并在调试MaintenaceTool 应用程序时手动调用它们作为参数。使用manual arguments 运行它让MaintenanceTool 运行(使用Qt 调试模式)并按预期工作,这让我很困惑(但没有显示管理员权限对话框弹出窗口 - 当时没有注意到)。

查看QProcess::startDetached() 实际Qt 代码,我终于遇到了一条消息error string(从未作为实际输出或errorString 发送)但存储在变量中。本质上,它提到它无法启动需要管理员权限的应用程序。因此,我搜索并发现了ShellExecuteEx 示例here。

我的实现ShellExecuteEx

QString args = QString("\"%1\" \"%2\" \"%3\" \"%4\" \"%5\"").arg(pid).arg(appName ).arg(logLocation).arg(newFilePath).arg(oldFilePath);

LPCWSTR 文件 = reinterpret_cast(updatorLocation.utf16());

LPCWSTR arg = reinterpret_cast(args.utf16());

SHELLEXECUTEINFO ShExecInfo = 0;

ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);

ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;

ShExecInfo.hwnd = NULL;

ShExecInfo.lpVerb = L"runas";

ShExecInfo.lpFile = 文件;

ShExecInfo.lpParameters = arg;

ShExecInfo.lpDirectory = NULL;

ShExecInfo.nShow = SW_SHOW;

ShExecInfo.hInstApp = NULL;

ShellExecuteEx(&ShExecInfo);

使用ShellExecuteEx 解决了我的问题并允许应用程序正常运行,当应用程序启动时会弹出runas 管理对话框。

我希望这对某人有所帮助!

【讨论】:

以上是关于运行自定义可执行文件,QProcess 立即退出,退出代码为 1的主要内容,如果未能解决你的问题,请参考以下文章

使用 QProcess 在 Qt 中运行外部可执行文件

QProcess 无法执行简单的控制台程序

QProcess 无法通过 QPushButton 执行终端行命令

qt怎么查看当前正在执行的代码

如何制作exe程序可执行文件

如果程序完成,QProcess exe 不会关闭