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

Run custom executable with QProcess exiting immediately with exit code 1

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

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 window 和编码输出,或者打开 cmd.exe 和 运行ning

C:\Path\To\AwesomeConsoleApp.exe

显示输出到 stdout 在同一个 cmd window.

进程信号触发如下:

  1. stateChanged Starting
  2. stateChanged Running
  3. QProcess::started
  4. stateChanged NotRunning
  5. QProcess::finished : 输出 Exit[1] 0

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

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

想删除这个问题,但万一它有用,我会post一个可能对以后的人有帮助的答案。

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

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

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

我尝试了以下与 QProcess 的组合,请注意,其中 none 对 运行 将应用程序作为管理员 有效!

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 argumentsMaintenanceTool 运行ning(使用 Qt 调试模式)并按预期工作,这让我很困惑(但没有显示管理员权限对话框弹出窗口- 当时没注意到)。

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

我的实施 ShellExecuteEx

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

LPCWSTR file = 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 = file;

ShExecInfo.lpParameters = arg;

ShExecInfo.lpDirectory = NULL;

ShExecInfo.nShow = SW_SHOW;

ShExecInfo.hInstApp = NULL;

ShellExecuteEx(&ShExecInfo);

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

希望对大家有所帮助!