QProcess whitspaces和参数的问题

时间:2018-11-23 10:43:25

标签: c++ qt process path arguments

我想通过QProcess调用可执行文件。可执行文件的路径可以包含空格。因此,我将引号放在可执行文件的路径周围。

但是,这仅在不添加任何参数的情况下才有效。

以下代码重现了该问题:

#include <QCoreApplication>
#include <QProcess>
#include <QDebug>
#include <QDir>

int main(int argc, char *argv[])
{
    int i = 0; // no whitespace, no argument -> works
    //    int i = 1; // whitespace with quotation, no arguments -> works
    //    int i = 2; // no whitespace, arguments -> works
    //    int i = 3; // whitespace with quotation, arguments -> works not

    QCoreApplication a(argc, argv);

    QProcess *process = new QProcess();

    QString pathToFile;
    QString absolutePathToProgram;
    pathToFile = "/home/user/tmp/file.xml";

    if (i == 0){
        absolutePathToProgram = "/home/user/tmp/executable";
    }else if(i == 1){
        absolutePathToProgram = "/home/user/tmp whitespace/executable";
        absolutePathToProgram = "\"" + absolutePathToProgram + "\"";
    }else if(i == 2){
        absolutePathToProgram = "/home/user/tmp/executable";
    }else if(i == 3){
        absolutePathToProgram = "/home/user/tmp whitespace/executable";
        absolutePathToProgram = "\"" + absolutePathToProgram + "\"";
    }

    QStringList arguments;
    arguments << pathToFile;

    if (i==0 || i==1){
        process->start(absolutePathToProgram);
    }else{
        process->start(absolutePathToProgram,arguments);
    }

    process->waitForFinished();

    QString output(process->readAllStandardOutput());

    qDebug() << output;

    return a.exec();
}

我添加了4种情况:

  • i == 0:可执行文件的路径不包含空格,并且我们不传递参数。这行得通
  • i == 1:可执行文件的路径确实包含空格,并且我们不传递参数。这行得通
  • i == 2:可执行文件的路径不包含空格,并且我们传递参数。这行得通
  • i == 3:可执行文件的路径确实包含空格,并且我们确实传递了参数。这不起作用

i == 3案例为何无效?

我正在使用Ubuntu作为操作系统。

奖励:

我还需要使其在Windows上运行。通常,在Windows上,我使用以下命令启动程序:

process->start("cmd.exe", QStringList() << "/c" << absolutePathToProgram << pathToFile);

我没有时间在Windows上进行测试,但是如果有人发布了答案并且也知道如何在Windows上创建解决方案,请告诉我。

2 个答案:

答案 0 :(得分:0)

可能是静态方法:

{
"private": true,
"scripts": {
    "dev": "npm run development",
    "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch": "npm run development -- --watch",
    "watch-poll": "npm run watch -- --watch-poll",
    "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
    "prod": "npm run production",
    "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},
"devDependencies": {
    "axios": "^0.18",
    "babel-preset-react": "^6.23.0",
    "bootstrap": "^4.0.0",
    "cross-env": "^5.1",
    "jquery": "^3.2",
    "laravel-mix": "^2.0",
    "lodash": "^4.17.11",
    "popper.js": "^1.12",
    "react": "^16.2.0",
    "react-dom": "^16.2.0"
},
"dependencies": {
    "@material-ui/core": "^3.3.2",
    "@material-ui/icons": "^3.0.1",
    "classnames": "^2.2.6",
    "gulp": "^4.0.0",
    "moment": "^2.22.2",
    "react-datetime": "^2.16.2",
    "react-google-maps": "^9.4.5",
    "react-loading": "^2.0.3",
    "react-modal": "^3.6.1",
    "react-places-autocomplete": "^7.2.0",
    "react-redux": "^5.0.7",
    "react-router-dom": "^4.3.1",
    "recompose": "^0.30.0",
    "redux": "^4.0.1",
    "redux-logger": "^3.0.6",
    "redux-thunk": "^2.3.0",
    "reselect": "^4.0.0",
    "throttle-debounce": "^2.0.1",
    "underscore": "^1.9.1",
    "validator": "^10.8.0"
}

可以为您提供帮助(同样具有交叉移植性)

例如

QDir::homePath()
QDir::toNativeSeparator(...) 

答案 1 :(得分:0)

我遇到了同样的问题。

我用这个(在python中)

也许您可以将正则表达式用于shlex部分

设置包含双引号空格的路径

导入shlex

def run(self):
    cli = shlex.split(self.commandfield.text(), posix=False)
    cmd = str(cli[0]) ### is the executable
    if (QStandardPaths.findExecutable(cmd)):
        print("command", cmd,  "found")
        del cli[0] ### delete first value in list
        t = " ".join(cli)
        if self.process.state() != 2:
            self.process.waitForStarted()
            self.process.waitForFinished()
            self.process.start((cmd + " " + t))
            print("running", self.process.program(), self.process.arguments())
        else:
            print("error ...")