QProcess fails with Qt 5.10.1 and Windows 10

一笑奈何 提交于 2019-12-24 09:55:22

问题


I recently compiled Qt 5.10.1 statically (mingw32) and the routine below now fails to work. I modified the code to include the full path for windows cmd "c:\windows\system32\cmd.exe" but that still doesn't work. Attempted with Windows 7 & 10. The code below works fine with Qt 5.6. Its job is to open a Windows terminal. Similar code to open a console in macOS and Linux works.

NOTE: This behavior is a bug introduced in Qt 5.8 see:

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);

回答1:


NOTE: This behavior with startDetached is a Windows-specific Qt bug introduced in Qt 5.8. The workaround is referenced at:

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();



回答2:


The correct way in Qt 5.10 is to pass arguments to QProcess program, so when you want to run cmd /k cpath.bat then the program is cmd and the arguments are /k xyz.bat . Also according to bug report QTBUG-64662, Qt does start the process starts but to make it appear, that might be related to win32 API, so using QProcess::setCreateProcessArgumentsModifier could be used to show the shell as describer in QProcess Documentation. So in your case:

#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();
}

And in order to create detached process, you can inherit QProcess and detach it after it starts, like this:

#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;
}


来源:https://stackoverflow.com/questions/49355396/qprocess-fails-with-qt-5-10-1-and-windows-10

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!