QProcess在Qt 5.10.1和Windows 10中失败

QProcess在Qt 5.10.1和Windows 10中失败,qt,qprocess,Qt,Qprocess,我最近静态编译了Qt5.10.1(mingw32),下面的例程现在无法工作。我修改了代码以包含windows cmd“c:\windows\system32\cmd.exe”的完整路径,但仍然不起作用。尝试使用Windows 7和10。下面的代码适用于Qt5.6。它的工作是打开一个Windows终端。类似的代码可以在macOS和Linux中打开控制台 注意:此行为是Qt 5.8中引入的错误,请参见: QString commstr=adbdir+“cpath.bat”; QFile文件(com

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

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

QString commstr=adbdir+“cpath.bat”;
QFile文件(commstr);
如果(!file.open)(QFile::WriteOnly|
QFile::Text)
{
日志文件(“创建cpath.bat时出错!”);
QMessageBox::critical(这是“,”创建bat文件时出错!”);
返回;
}
QTextStream out(文件(&F);

out在Qt5.10中,正确的方法是将参数传递给QProcess程序,因此当您想要运行
cmd/k cpath.bat
时,程序是
cmd
,参数是
/k xyz.bat
。同样根据bug报告,Qt确实启动了进程,但为了让它看起来像win32 API,这可能与win32 API有关,因此可以使用
QProcess::setCreateProcessArgumentsModifier
来显示中描述的shell。 因此,在你的情况下:

#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();
}
#包括“Windows.h”
int main(int argc,char*argv[]){
QApplication应用程序(argc、argv);
QProcess过程;
QString program=“cmd.exe”;
QStringList参数=QStringList()标志|=CREATE_NEW_控制台;
args->startupInfo->dwFlags&=~STARTF\u USESTDHANDLES;
});
进程启动(程序、参数);
process.waitForStarted();
返回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;
}
#包括
#包括
#包括
#包括
#包括“Windows.h”
类QDetachableProcess
:公共QProcess{
公众:
QDetachableProcess(QObject*parent=0)
:QProcess(父进程){
}
void detach(){
waitForStarted();
setProcessState(QProcess::NotRunning);
}
};
int main(int argc,char*argv[]){
QDetachableProcess过程;
QString program=“cmd.exe”;
QStringList arguments=QStringList()startupInfo->dwFlags&=~STARTF_USESTDHANDLES;
});
进程启动(程序、参数);
process.detach();
返回0;
}

注意:startDetached的这种行为是Qt5.8中引入的Windows特有的Qt错误。该变通方法在以下位置引用:


哪个编译器?问题编辑为显示mingw32。不起作用。我使用了如图所示的代码,但没有终端。Qprocess在其他情况下工作,因此编辑StartedDetailed?问题时一定会出现问题,以添加macOS和Linux的类似代码工作的事实。这只是Windows(10/7)的问题。@Alan这只是
cmd.exe
(shell)的行为方式。。它确实在后台启动,并在您看不到交互式shell的情况下执行您的命令。但是为了保持shell运行,您需要在更新答案时进行一些修改。@Alan,您可以使用以前的答案代码测试任何其他程序,如
notepad.exe
。。。它可以根据需要工作。正如我提到的,
cmd.exe
根据您的本地开发环境设置而有所不同,默认设置是cmd.exe启动后台shell而不是交互式shell。替换记事本确实有效,感谢测试和示例代码。对于Qt5.6和之前的5.x Qt,传递/k参数就足以保持cmdshell打开。我发布的代码是分配给按钮的功能。非常简单,使用两年多。仍然可以使用5.6,我只是重新编译并测试了它。
#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;
}
   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();