QT QProcess 启用CMD.exe,实现交互多次执行读写指令(在Win7平台)

aming090 2017-08-17 01:34:38
因项目要在Windows下开启CMD程序,通过与CMD程序交互进行读写,
举例:开启CMD程序 按顺序执行如下指令,每执行一条指令后,并读取CMD的反馈信息,再执行下一条指令,再读取CMD反馈信息,当指令全部都执行完毕后,再关闭CMD程序;
0.cd f:\test(进入f:\test\目录);
1.dir(查看当前目录文件);
2.ver (查看系统版本);
3.ipconfig(查看IP地址);
4.time (查看当前时间);
5.ping 192.168.1.1 -n 10 (Ping路由器地址);
6.iperf -s (执行iperf指令);


备注:把读CMD输出信息动作放至到while中让它循环读取CMD的输出信息,写一条读一条,就像串口通信一样;

目前状态是:通过QProcess启动CMD,可以读出CMD启动时输出的信息,但后面再调用进程调用wirte(QString *)给CMD下指令,wirte执行完成后,CMD没有任何反馈?

在论坛上找了好久没有和我用法相同的情况,CSDN最良心博客"一去二三里"也没有类似示例,请问那路前辈,大侠,谁这样弄过,我该要如何写? 第一次用QT,麻烦大家了


如下是我的代码:

#include<QApplication.h>
#include<QWidget.h>
#include<QDialog.h>
#include<QTextcodec.h>
#include<QString.h>
#include "MainWindow.h"

int main(int argc, char*argv[])
{
QApplication a(argc,argv);
QTextCodec *codec = QTextCodec::codecForName("GBK");
QTextCodec::setCodecForTr(codec);
QTextCodec::setCodecForLocale(QTextCodec::codecForLocale());
QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());

MainWindow w;
w.show();
return a.exec();
}

//------------------------------------------workthread.h file------------------------------------------

#ifndef WORKTHREAD_H
#define WORKTHREAD_H

#include<QObject.h>
#include<QWidget.h>
#include<QThread.h>
#include<QString.h>
#include<Qthread.h>

class QProcess;

class workthread:public QObject
{
Q_OBJECT

public:
explicit workthread( QObject *param=0);
~workthread();

bool b_loopread;

public:
QProcess* myChildProcess;


public slots:
void read_slot();
void write_slot(QString );
void stopread_slot();
void IniCmdThread_slot();

// void doWork(int parameter)
// {
// qDebug()<<"receive the execute signal---------------------------------";
// qDebug()<<" current thread ID:"<<QThread::currentThreadId();

// for(int i = 0;i!=1000000;++i)
// {
// ++parameter;
// }

// qDebug()<<" finish the work and sent the resultReady signal\n";
// emit resultReady(parameter);
// }

signals:
void senddata_sign(QString);

private:
void Delay_MSec(unsigned int msec);
};

#endif // WORKTHREAD_H

//------------------------------------------workthread.cpp file------------------------------------------
#include"workthread.h"
#include <QCoreApplication>
#include <QProcess>
#include <QDebug.h>
#include <QString>
#include <QTime>
workthread::workthread(QObject *param):
QObject(param)
{
b_loopread=false;

}
workthread::~workthread()
{
myChildProcess->close();

delete myChildProcess;

myChildProcess=NULL;
qDebug() << "end myChildProcess " << "\r\n";

}

void workthread::IniCmdThread_slot()
{
qDebug() << "IniCmdThread_slot()";
myChildProcess = new QProcess(this);
myChildProcess->setProcessChannelMode(QProcess::MergedChannels);
QObject::connect(myChildProcess,SIGNAL(readyReadStandardOutput()),this,SLOT(read_slot()));
myChildProcess->start("CMD.exe");
if (!myChildProcess->waitForStarted())
qDebug() << "Make failed:" << myChildProcess->errorString();
else
{
// qDebug() << "Child Process Started.123 " << myChildProcess->readAll();
b_loopread=true;
}
}

void workthread::read_slot()
{
while(b_loopread)
{
Delay_MSec(1000);
// if(myChildProcess->waitForReadyRead())
// {
char output[128];
qint64 rec=myChildProcess->readLine(output,127);
if((strlen(output)!=0)&&(rec!=-1))
{
QString tmpstr;
tmpstr=output;
emit senddata_sign((QString)tmpstr);
qDebug() << tmpstr;
}
// }
}
}

void workthread::write_slot(QString strWrite)
{
char*ch;
QByteArray ba = strWrite.toLatin1();
ch=ba.data();
myChildProcess->write("dir\r");
myChildProcess->waitForBytesWritten(2000);

// if(myChildProcess->waitForBytesWritten())
// {
qDebug() <<"workthread::write_slot "<<strWrite;
// }
}

void workthread::stopread_slot()
{
b_loopread=false;
}

void workthread::Delay_MSec(unsigned int msec)
{
QTime _Timer = QTime::currentTime().addMSecs(msec);

while( QTime::currentTime() < _Timer )

QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}



//----------------------MainWindow.h---------------------------------

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include<QApplication.h>
#include <QWidget>
//#include"ParentProcess.h"
#include"workthread.h"

namespace Ui{
class MainWindow;
}

class MainWindow: public QWidget
{

Q_OBJECT
QThread workerThread;

public:
explicit MainWindow(QWidget *param=0);
~MainWindow();


signals:
void IniCmdThread_sign();
void read_sign();
void write_sign(QString);
void stopread_sign();
void sendcomd_sign(QString);


public slots:
void SendCommand();
void getdata_slot(QString);
void stopRead();

private:
QString str_rece_total;
Ui::MainWindow *MUi;

// ParentProcess* obj;


};

#endif // MAINWINDOW_H


//----------------------MainWindow.cpp---------------------------------

#include"MainWindow.h"
#include"ui_MainWindow.h"
#include <QProcess>
#include <QThread>
#include <QByteArray>
#include <QDebug>
#include <QTextCodec>

MainWindow::MainWindow(QWidget* param):
QWidget(param),
MUi(new Ui::MainWindow)
{
MUi->setupUi(this);
workthread *work=new workthread;
work->moveToThread(&workerThread);
// QTextCodec::setCodecForTr=QTextCodec::codeForName("UTF-8");


connect(this, SIGNAL(IniCmdThread_sign()), work, SLOT(IniCmdThread_slot()));


// connect(&workerThread,SIGNAL(&QThread::finished()), work,SLOT(&QObject::deleteLater()));

connect(this, SIGNAL(write_sign(QString)), work, SLOT(write_slot(QString)));
connect(this, SIGNAL(read_sign()), work, SLOT(read_slot()));
connect(MUi->btnStop,SIGNAL(clicked()), this, SLOT(stopRead()));
connect(this, SIGNAL(stopread_sign()), work, SLOT(stopread_slot()));

connect(work,SIGNAL(senddata_sign(QString)),this,SLOT(getdata_slot(QString)));
connect(this,SIGNAL(sendcomd_sign(QString)),work,SLOT(write_slot(QString)));
connect(MUi->btnSend,SIGNAL(clicked()),this,SLOT(SendCommand()));

workerThread.start();


qDebug()<<"current Main thread ID:"<<QThread::currentThreadId()<<'\n';
emit IniCmdThread_sign();


emit read_sign();
}

MainWindow::~MainWindow()
{
emit sendcomd_sign("exit\r\n");
workerThread.quit();
workerThread.wait();
delete MUi;
}

void MainWindow::getdata_slot(QString info)
{
QString str_info="Recevie:";
str_info.append(info);
str_info.append("\n");
str_rece_total.prepend(str_info);

MUi->txtMain->setText(str_rece_total);
}

void MainWindow::SendCommand()
{
QString str_comd=MUi->txtEditComd->toPlainText();
str_comd+='\r';
emit sendcomd_sign(str_comd);
}

void MainWindow::stopRead()
{
emit stopread_sign();
}

//void MainWindow::RunTest()
//{
// qDebug() << "1235477777";

// qDebug()<<"Read";
// QString outData = obj->myChildProcess->readAllStandardOutput();
// qDebug()<<outData;
// MUi->txtMain->setText(outData);
//}
[code=c]
[/code]
...全文
4168 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
LVsler 2020-11-12
  • 打赏
  • 举报
回复
引用 6 楼 J0722F 的回复:
我这边和你有个区别就是串口必须保持连接,也就是说第二条指令开始,剩下的指令都要在有连接该串口的基础上才能执行成功
请问你解决了么,我也遇到这个问题了,Qt5.7.1
LVsler 2020-11-12
  • 打赏
  • 举报
回复
请问你解决了么,我也遇到这个问题了,Qt5.7.1
J0722F 2020-02-26
  • 打赏
  • 举报
回复
我这边和你有个区别就是串口必须保持连接,也就是说第二条指令开始,剩下的指令都要在有连接该串口的基础上才能执行成功
J0722F 2020-02-26
  • 打赏
  • 举报
回复
void CMDProcess::IniCmdThreadSlot() { JF_DBG << "IniCmdThread_slot()"; m_process = new QProcess(this); m_process->setProcessChannelMode(QProcess::MergedChannels); QObject::connect(m_process,SIGNAL(readyReadStandardOutput()),this,SLOT(readSlot())); QObject::connect(m_process, SIGNAL(error(QProcess::ProcessError)),this, SLOT(showCMDError())); m_process->start("cmd"); // m_process->start("proxmark3", QStringList("Com3")); m_process->waitForBytesWritten(2000); // QStringList comd; // comd<<"hf"<<"14a"<<"reader"; // m_process->start("proxmark3", comd); QByteArray output = m_process->readAllStandardOutput(); QString str_output = output; JF_DBG<<str_output; if (!m_process->waitForStarted()) JF_DBG << "Make failed:" << m_process->errorString(); else { JF_DBG << "Child Process Started.123 " << m_process->readAll(); } } 这边我试过直接启动自己编译的exe,并带入参数,可是可以,但还是没数据返回 正常应该是:
J0722F 2020-02-26
  • 打赏
  • 举报
回复
你好!我遇到了跟你一样的问题,根据你说的添加了“while(myChildProcess->canReadLine())”但还是就只有个启动cmd时返回的信息!!不过我是第二次开始就执行一个.exe里的命令就是了, 能不能帮忙看看
aming090 2017-08-17
  • 打赏
  • 举报
回复
已经解决,void workthread::read_slot() 的while循环内没有进行有效判断 ,造成了阻塞,没有办法写值, 我已经改成如下,可以正常读写了: void workthread::read_slot() { while(myChildProcess->canReadLine()) { char output[1024]; int ret = myChildProcess->readLine(output,1023); qDebug() << ret; qDebug() << output; QString tmpstr; tmpstr=output; emit senddata_sign((QString)tmpstr); qDebug() << tmpstr; } }
  • 打赏
  • 举报
回复
可以关联一下QProcess的 void error(QProcess::ProcessError error);信号,看看有没有错误发生

16,225

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧