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