当进程结束时,如何保持QProcess执行的命令?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当进程结束时,如何保持QProcess执行的命令?相关的知识,希望对你有一定的参考价值。

在Linux系统中终止GUI程序后,我正试图找到一种方法来保持QProcess执行的命令。现在,当进程结束时,所有执行的命令都消失了。在QProcess终止后有没有办法保持这个?

// code which executes command in linux
QProcess *mproc = new Qprocess(this);
QStringList args;
mproc->setWorkingDirectory("/home/test");
args << "-c" << "source tool_def1.env; source tool_def2.env; myProg";
mproc->start("/bin/csh", args);

tool_def1.envtool_def2.env文件包含一些用于执行myProg的环境变量,如set path = (~~~~)

在GUI程序中,这段代码做得很好。并且,我想在GUI程序终止后运行GUI程序的终端中执行myProg程序。

但是,如果GUI程序终止,我无法运行myProg,因为tool_def1.envtool_def2.env文件的环境变量消失了。

是否可以保留环境变量?或者,是否有可能在myProg进程的环境变量的其他过程中执行mproc程序如下?

QProcess *mproc2 = new QProcess(this);
mproc2->setWorkingDirectory("/home/test2");
mproc2->start("myProg");
答案

您使用的QProcess::startDetached的重载是一种静态方法,因此它不会考虑特定实例的属性,即mproc->setWorkingDirectory("/home/test")不会为静态方法设置工作目录,仅适用于mproc。启动进程时,由于未为静态调用设置工作目录,因此无法找到程序并且程序失败。

正如您在文档中看到的那样,静态startDetached也允许将工作目录作为参数,因此您可以将代码更改为:

QStringList args;
args << "-c" << "source tool_def1.env; source tool_def2.env; myProg";
QProcess::startDetached("/bin/csh", args, "/home/test");

另一种方法是使用非静态版本,这需要单独指定程序:

QProcess mproc(this);

QStringList args;
args << "-c" << "source tool_def1.env; source tool_def2.env; myProg";
mproc.setArguments(args);

mproc.setWorkingDirectory("/home/test");
mproc.setProgram("/bin/csh");

qint64 pid; // to store the process ID (will become invalid if the child process exits)
mproc.startDeatached(&pid);

关于你的第二个问题,请看看QProcess::setProcessEnvironment。只是你必须使用非静态方式来设置进程的环境。您可以使用QProcess::systemEnvironment获取当前进程的环境变量。

mproc.setProcessEnvironment(QProcess::systemEnvironment());

从评论更新:如果您想在GUI应用程序运行时始终使用活动的环境变量(是某种配置器吗?),您可以将它们保存到文件(例如JSON),然后手动加载和设置它们从第二个过程。

要提取它们,您可以执行以下操作:

const auto env_vars = QProcess::systemEnvironment().toStringList();

现在env_vars将是一个格式为NAME_OF_ENVAR=VALUE_OF_ENVAR的字符串列表。您可以将此类列表保存到文件中(您需要在每行的开头添加一个export以便与source一起使用)。


我已经在Windows中测试了静态版本(VS 15.8.2和Qt 5.10.0)并且它按预期工作。使用的代码:

#include <qprocess.h>

int main(int argc, char* argv[])
{
  QProcess::startDetached("cmd", QStringList() << "/c" << "test.exe", "../test/");

  return 0;
}

其中test.exe的代码基本上是一个永无止境的过程。


注意:一个有趣的事实,并作为使用VS的开发人员的注释。对于相同的程序和构建,如果从命令行执行它可以正常工作:应用程序结束,第二个进程在后台继续运行,但如果从VS IDE执行,则控制台窗口保持活动状态,如果我关闭它,第二个过程也被杀死了。调试时,调试器结束但仍显示控制台。我想这是因为VS在从IDE启动时以某种方式跟踪所有创建的进程。

以上是关于当进程结束时,如何保持QProcess执行的命令?的主要内容,如果未能解决你的问题,请参考以下文章

Qt QProcess startDetached 无法结束进程(bash 会话)

如何在 Windows 上通过 QProcess 启动提升的子进程?

如何关闭 Qt 子进程并让子进程执行清理代码?

Qt笔记-QProcess切换用户执行进程(Linux)

需要 virtenv 时如何运行 QProcess?

QT使用QProcess类,判断某个进程是否存在