QProcess在Qt 5.10.1和Windows 10中失败

时间:2018-03-19 03:27:52

标签: qt qprocess

我最近静态编译了Qt 5.10.1(mingw32),现在下面的例程无法正常工作。我修改了代码以包含windows cmd“c:\ windows \ system32 \ cmd.exe”的完整路径,但仍然无效。尝试使用Windows 7& 10.下面的代码适用于Qt 5.6。它的工作是打开一个Windows终端。类似的代码在macOS和Linux中打开控制台。

注意:此行为是Qt 5.8中引入的错误,请参阅:

https://bugreports.qt.io/browse/QTBUG-57687

    QString commstr = adbdir+"cpath.bat";
    QFile file(commstr);

        if(!file.open(QFile::WriteOnly |
                      QFile::Text))
        {
            logfile("error creating cpath.bat!");
            QMessageBox::critical(this,"","Error creating bat file!");
            return;
        }

        QTextStream out(&file);
        out  << "set PATH=%PATH%;"+QDir::currentPath()+";"<< endl;

        file.flush();
        file.close();

        cstring = "cmd /k " +QDir::currentPath()+"/cpath.bat";
        QProcess::startDetached(cstring);

2 个答案:

答案 0 :(得分:2)

注意:startDetached的这种行为是Qt 5.8中引入的Windows特定的Qt错误。解决方法在以下位置引用:

https://bugreports.qt.io/browse/QTBUG-57687

   QProcess p;
        p.setProgram("cmd.exe");
        p.setArguments({"/k", QDir::currentPath()+"/cpath.bat"});
        p.setCreateProcessArgumentsModifier([] ( 
    QProcess::CreateProcessArguments
        *args) {
                args->flags &= ~CREATE_NO_WINDOW;
            });
        p.startDetached();

答案 1 :(得分:0)

Qt 5.10中的正确方法是将参数传递给QProcess程序,因此当您想运行cmd /k cpath.bat时,程序为cmd且参数为/k xyz.bat。另外根据错误报告QTBUG-64662,Qt确实启动了流程启动,但要使其显示,这可能与win32 API有关,因此可以使用QProcess::setCreateProcessArgumentsModifier将shell显示为{{{ 3}}。 所以在你的情况下:

#include "Windows.h"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    QProcess process;
    QString program = "cmd.exe";
    QStringList arguments = QStringList() << "/K" << QDir::currentPath()+"/cpath.bat";
    process->setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args)
    {
        args->flags |= CREATE_NEW_CONSOLE;
        args->startupInfo->dwFlags &= ~STARTF_USESTDHANDLES;
    });
    process.start(program, arguments);
    process.waitForStarted();
    return app.exec();
}

为了创建分离进程,您可以继承QProcess并在启动后将其分离,如下所示:

#include <QProcess>
#include <QString>
#include <QStringList>
#include <QDir>
#include "Windows.h"

class QDetachableProcess
        : public QProcess {
public:
    QDetachableProcess(QObject *parent = 0)
        : QProcess(parent) {
    }
    void detach() {
       waitForStarted();
       setProcessState(QProcess::NotRunning);
    }
};

int main(int argc, char *argv[]) {
    QDetachableProcess process;
    QString program = "cmd.exe";
    QStringList arguments = QStringList() << "/K" << QDir::currentPath()+"/cpath.bat";
    process.setCreateProcessArgumentsModifier(
                [](QProcess::CreateProcessArguments *args) {
        args->flags |= CREATE_NEW_CONSOLE;
        args->startupInfo->dwFlags &=~ STARTF_USESTDHANDLES;
    });
    process.start(program, arguments);
    process.detach();
    return 0;
}