解决QProcess使用setProcessEnvironment环境变量不能生效的问题

使用QProcess运行进程时,为了方便使用运行程序,直接使用程序名字运行。但是这时候需要设置环境变量。可是使用setProcessEnvironment怎么设置也不能设置成功。运行QProcess却是一直返回’文件找不到’的现象。下面让我们来窥探究竟吧。

不能正确使用环境变量的代码

1
2
3
4
5
QProcess* myProcess = new QProcess(this);
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("PATH", "C:/AppPath;" + env.value("PATH"));
myProcess->setProcessEnvironment(env);
myProcess->start("App.exe");

可以正确设置环境变量的代码

1
2
3
4
5
QProcess* myProcess = new QProcess(this);
QString path = "C:/AppPath;" + qgetenv("PATH");
qputenv("PATH", path.toStdString().c_str());
myProcess->setProcessEnvironment(env);
myProcess->start("App.exe");

为什么会这样?

  • 先看下列源代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    bool QProcessPrivate::callCreateProcess(QProcess::CreateProcessArguments *cpargs)
    {
    if (modifyCreateProcessArgs)
    modifyCreateProcessArgs(cpargs);
    bool success = CreateProcess(cpargs->applicationName, cpargs->arguments,
    cpargs->processAttributes, cpargs->threadAttributes,
    cpargs->inheritHandles, cpargs->flags, cpargs->environment,
    cpargs->currentDirectory, cpargs->startupInfo,
    cpargs->processInformation);
    if (stdinChannel.pipe[0] != INVALID_Q_PIPE) {
    CloseHandle(stdinChannel.pipe[0]);
    stdinChannel.pipe[0] = INVALID_Q_PIPE;
    }
    if (stdoutChannel.pipe[1] != INVALID_Q_PIPE) {
    CloseHandle(stdoutChannel.pipe[1]);
    stdoutChannel.pipe[1] = INVALID_Q_PIPE;
    }
    if (stderrChannel.pipe[1] != INVALID_Q_PIPE) {
    CloseHandle(stderrChannel.pipe[1]);
    stderrChannel.pipe[1] = INVALID_Q_PIPE;
    }
    return success;
    }
  • QProcess底层调用的是Window系统CreateProcess接口,但是该调用是为了获取可执行文件的完整路径或相对于当前工作目录的路径。

  • 虽然它确实改变了生成过程的环境, 但是却无法设置搜索可执行文件的环境。

怎么正确设置可执行文件的环境变量?

  • 使用qgetenvqputenv设置。