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