Как мне сохранить команду, выполняемую QProcess, когда процесс завершится? - PullRequest
0 голосов
/ 30 августа 2018

Я пытаюсь найти способ сохранить команды, выполняемые QProcess после завершения программы GUI в системе Linux. Теперь, когда процесс заканчивается, все выполняемые команды исчезают. Есть ли способ сохранить это после завершения 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.env и tool_def2.env включены некоторые переменные среды для выполнения myProg, например set path = (~~~~).

В программе с графическим интерфейсом этот код хорошо сделан. И я хочу выполнить myProg программу в терминале, программа GUI которого запускается после завершения программы GUI.

Но, если программа с графическим интерфейсом завершена, я не могу запустить myProg, потому что переменные окружения tool_def1.env и tool_def2.env файла исчезают.

Можно ли сохранить переменные среды? Или можно выполнить программу myProg в другом процессе с переменными среды процесса mproc, как показано ниже?

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

1 Ответ

0 голосов
/ 30 августа 2018

Используемая вами перегрузка 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());

Обновление по комментариям: если вы хотите всегда использовать переменные среды, активные во время работы приложения с графическим интерфейсом (это какой-то конфигуратор?), Вы можете просто сохранить их в файл (например, 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 * Код 1040 * - это, по сути, бесконечный процесс.


Примечание : Интересный факт, а также примечание для разработчика, использующего VS. Для той же программы и сборки, если она выполняется из командной строки, она работает правильно: приложение завершается, а второй процесс продолжает работать в фоновом режиме, но если он выполняется из IDE VS, то консольное окно 1047 * остается активным и если я закрою его, второй процесс тоже будет убит. После отладки отладчик завершает работу, но консоль все еще отображается. Я полагаю, это потому, что VS каким-то образом отслеживает все созданные процессы при запуске из IDE.

...