qt做的软件的更新程序!

更新的是一个主程序的辅助程序及辅助程序的配置文件和dll 有一些细节就是当主程序的辅助程序需要更新的时候 需要告诉主程序暂时不能调用辅助程序 并且在更新完毕之后告诉主程序可以调用了 其他细节包括无边窗移动啊 状态码返回什么的需要的可以仔细看看我写的代码吧

大体思路是这样的 (图不重要看字)




直接源码

.pro

#-------------------------------------------------

#
# Project created by QtCreator 2015-08-27T08:50:20
#
#-------------------------------------------------
QT       += core gui
QT += network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Sdup
TEMPLATE = app
SOURCES += main.cpp\
        mainwindow.cpp
HEADERS  += mainwindow.h
FORMS    += mainwindow.ui
RESOURCES += \
    photo.qrc

.h

#ifndefMAINWINDOW_H

#define MAINWINDOW_H
#include <QMainWindow>
#include<QSettings>
#include<QNetworkAccessManager>
#include<QNetworkReply>
#include<QNetworkRequest>
#include<QDebug>
#include<QStringList>
#include<QVariant>
#include<QVariantMap>
#include<QJsonDocument>
#include<QJsonParseError>
#include<QFile>
#include<QMessageBox>
#include<QTextCodec>
#include<QEventLoop>
#include<QFileInfo>
#include<QDir>
#include<QString>
#include<QPoint>
#include<QMouseEvent>
#include<QPalette>
#include<QBrush>
#include<QPainter>
#include<QProcess>
//
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
QString read_configure();//获取更新配置文件
void postallconfigure();//发送需要检测的信息接收返回信息
void checkallbackdata();//处理所有的返回的结果 比较版本号和挑出需要更新的版本号!
void copytoanother(const QString &source,const QString &destination);//复制文件到另一个文件夹
bool downfiles(QString url,QString downfilename);//下载需要更新的文件!
void writeinifile(QString name,QString verson);//判断文件是不是新增并更改配置文件的名字和版本号
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
QPoint windowPos;
QPoint mousePos ;
QPoint dPos;
void paintEvent(QPaintEvent *event);

private slots:
void updateprogressBar(qint64 bytesRead, qint64 totalBytes);

private:
    Ui::MainWindow *ui;
    QString checkurl;
    int updatefilenumber;//需下载的更新文件数量
    QStringList newfiles;//新增的文件
    QStringList failfiels;//下载失败的文件
    QProcess *testprocess;
};
#endif // MAINWINDOW_H


.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
/*
* 配置文件  更新程序的 Sdup.yanxuetao更新配置文件 同级文件夹两个 Downtemp SDLL 均可自动创建
* D58的 city.ini AllCity.abcd 城市转换得时候使用的  wubajiami.jde 解密使用 记得调用的时候把D58.dll改为1.dll
* 记得测试配置文件 不存在
* 配置文件为空 (记得记录返回内容)
* 如果配置文件为空的话(可能所有的dll都被删了)重新生成配置文件遍历dll所在文件夹获取现存的所有的文件全部标为最低配 然后检测更新
* 配置文件不存在的时候记得配置文件中的信息初始化 检测url分区
* 接的要写检测群发更新网址的 更新
* 更改程序中加载dll以及dll所需的配置文件的路径 修改为SDLL/dll名字
*/
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //  testprocess=new QProcess(this);
    //  connect(testprocess,SIGNAL(finished(int)),this,SLOT(test()));
    //  testprocess->start("F:/111111111111111111111111foryfds/fabunew/Sdup.exe");
    //  qDebug()<< testprocess->state();
    //  qDebug()<<testprocess->isOpen();
    ui->progressBar->hide();
    ui->label  ->setStyleSheet("color: rgb(235, 235, 117);font-size : 24px");
    ui->label_2->setStyleSheet("color: rgb(0, 255, 127);font-size : 24px");
    ui->label_3->setStyleSheet("color: rgb(0,255,255);font-size : 22px");
    this->setWindowOpacity(1);
    this->setWindowFlags(Qt::FramelessWindowHint);
    this->setAttribute(Qt::WA_TranslucentBackground);
    this->setAutoFillBackground(true);
    
    this->read_configure();
    //this->read_configure();
    //this->checkallbackdata();
    //this->copytoanother("ww.txt","123/w2220w.txt");
    
    //this->downfiles("http://192.168.1.30:8017/userfile/2016/8/16/1.png","1.png");
    //this->writeinifile("1","1.0");
    //this->writeinifile("6","666");
    //this->writeinifile("闫雪涛","闫雪涛");
}
MainWindow::~MainWindow()
{
    delete ui;
}
//获取所有的可能更新的数据
QString MainWindow::read_configure()
{
    QJsonDocument tojson;
    QVariantMap allsenddata;
    QFile configuresfile("Sdup.yanxuetao");
    
    if(configuresfile.exists()){//存在为空或者有错误!!!
        QSettings configures("Sdup.yanxuetao", QSettings::IniFormat);
        QTextCodec *codec = QTextCodec::codecForName("gb2312");
        configures.setIniCodec(codec);
        qDebug()<< configures.NoError<<1111111111111<<configures.status();
        configures.beginGroup("Dll");
        qDebug()<<configures.group()<<configures.allKeys()<<configures.value("1");
        //数据封装
        qDebug()<<checkurl;
        
        for (int alldll=0;alldll<configures.allKeys().size();alldll++)
        {
            qDebug()<<"allsenddata0000000000";
            allsenddata.insert(configures.allKeys().at(alldll),configures.value(configures.allKeys().at(alldll)));
            qDebug()<<allsenddata;
        }
        tojson=QJsonDocument::fromVariant(allsenddata);
        qDebug()<< tojson.toJson();
        configures.endGroup();
        configures.beginGroup("Url");
        checkurl=configures.value("CheckUrl").toString();
        qDebug()<<checkurl;
        return QString(tojson.toJson());
    }else
    {//不存在
        //创建配置文件
        configuresfile.open(QIODevice::WriteOnly);
        configuresfile.flush();
        configuresfile.close();
        QSettings addnewfiles("Sdup.yanxuetao", QSettings::IniFormat);
        QTextCodec *codec = QTextCodec::codecForName("gb2312");
        addnewfiles.setIniCodec(codec);
        //写入固定的检测群发是否有更新的网址
        addnewfiles.beginGroup("Dll");
        addnewfiles.setValue("YfFf.exe","1.0");
        addnewfiles.endGroup();
        addnewfiles.beginGroup("Url");
        addnewfiles.setValue("CheckUrl","http//:test.**");
        addnewfiles.endGroup();
        //遍历存放dll的文件夹 不存在就创建新的存放文件夹  文件夹内容为空就什么都没有喽  发送为空的时候记得返回的要有些基本的dll返回过过来下载
        QDir alldllsdir;
        if(!alldllsdir.exists("SDLL"))
        {
            alldllsdir.mkdir("SDll");
            //低配置来写配置文件 还是写入检测网址
            qWarning("群发dll不存在!!已创建SDLL文件夹!!");
            
        }else
        {
            //[Url]
            //CheckUrl=http//:test.**
            //遍历存放dll的文件夹 取出文件 按低版本写入文件
            alldllsdir.setFilter(QDir::Files | QDir::NoSymLinks);
            alldllsdir.setPath("SDLL");
            QFileInfoList list = alldllsdir.entryInfoList();
            addnewfiles.beginGroup("Dll");
            for(int i=0; i<list.count(); i++)
            {
                qDebug()<<   list.at(i).fileName();
                //低配置装进配置问文件中
                addnewfiles.setValue(list.at(i).fileName(),QString("1.0"));
            }
        }
        QSettings configures("Sdup.yanxuetao", QSettings::IniFormat);
        configures.setIniCodec(codec);
        configures.beginGroup("Dll");
        qDebug()<<configures.group()<<configures.allKeys()<<configures.value("1");
        //数据封装
        qDebug()<<checkurl;
        
        for (int alldll=0;alldll<configures.allKeys().size();alldll++)
        {
            
            allsenddata.insert(configures.allKeys().at(alldll),configures.value(configures.allKeys().at(alldll)));
            
        }
        tojson=QJsonDocument::fromVariant(allsenddata);
        qDebug()<< tojson.toJson();
        configures.endGroup();
        configures.beginGroup("Url");
        checkurl=configures.value("CheckUrl").toString();
        qDebug()<<checkurl<<QString(tojson.toJson());
        return QString(tojson.toJson());
    }
}
void MainWindow::postallconfigure()
{
    QNetworkAccessManager *postmanager=new QNetworkAccessManager(this);
    QEventLoop postevent;//设置循环事件
    //先按post来写 要不要设置验证啥的
    QNetworkReply *getcheckeddata=postmanager->post(QNetworkRequest(QUrl(checkurl)),this->read_configure().toLatin1());
    QObject::connect(getcheckeddata,SIGNAL(finished()),&postevent,SLOT(quit()));
    postevent.exec();
    if(getcheckeddata->error()==QNetworkReply::NoError)//先判断是不是有错返回
    {//获取所有的结果!
        QString allbackdata=getcheckeddata->readAll();
        qDebug()<<allbackdata;
        //处理接收到结果!!
    }else
    {//有错的处理!!
        qWarning()<<"接受返回更新数据有误!!";
        exit(0);
    }
    
}
void MainWindow::checkallbackdata()
{
    QString allbackdata("{\"1111.dll\": \"2.0\",\"CheckUrl\": \"http//:www.yxttest.com\",\"2.dll\": \"2.0\",\"31.dll\": \"3.0\",\"sda.exe\": \"2.0\",\"sda1.exe\": \"2.0\",\"sda2.exe\": \"2.0\",\"sda3.exe\": \"2.0\",\"sda4.exe\": \"2.0\",\"sda5.exe\": \"2.0\",\"DownUrl\": \"http://192.168.1.30:8017/userfile/2016/8/16/\"}");
    QJsonParseError jsonerror;
    QJsonDocument checkjsondocument = QJsonDocument::fromJson(allbackdata.toUtf8(), &jsonerror);
    if (jsonerror.error == QJsonParseError::NoError)
    {
        if (checkjsondocument.isObject())
        {
            QVariantMap result = checkjsondocument.toVariant().toMap();
            QVariantMap::Iterator aa;
            qDebug ()<<result.size()<<result.keys()<<result.values()<<result["DownUrl"].toString()<<"10234646";
            //下载需要更新的文件 修改配置文件
            QString downurl=result["DownUrl"].toString();
            int i=0;
            allbackdata.contains("CheckUrl")? updatefilenumber =result.size()-2: updatefilenumber =result.size()-1;
            
            qDebug()<<"需要更新文件数量为:"<<updatefilenumber;
            int number=updatefilenumber;
            ui->progressBar->show();
            ui->label->setText(QString("需更新:%1").arg(QString::number(updatefilenumber)));
            ui->label_2->setText(QString("剩余:%1").arg(QString::number(updatefilenumber)));
            for( aa=result.begin();aa!=result.end();aa++)
            {
                if(aa.key()!=QString("DownUrl"))
                {
                    if(aa.key()==QString("CheckUrl"))
                    {//如果检测更新的网址变了
                        this->writeinifile(QVariant(aa.key()).toString(),QVariant(aa.value()).toString());
                    }
                    else{
                        qDebug()<< aa.key()<<aa.value();
                        //判断是不是新文件//找到文件 转移到临时文件夹
                        QFile::exists(QString("SDLL/").append( aa.key()))? aa.key()==QString("YfFf.exe")?this->copytoanother( QVariant(aa.key()).toString(),QString("DownTemp/").append(QVariant(aa.key()).toString())): this->copytoanother(QString("SDLL/").append( QVariant(aa.key()).toString()),QString("DownTemp/").append(QVariant(aa.key()).toString())):qDebug("新文件");
                        
                        //下载
                        if( this->downfiles(result["DownUrl"].toString().append(aa.key()),aa.key()))
                        {//如果下载成功!!
                            if(QFile::exists(QString("DownTemp/%1").arg(aa.key())))
                            {
                                qDebug()<<"下载成功,正在移除临时文件!!!"<<i;
                                QFile::remove(QString("DownTemp/%1").arg(aa.key()));
                            }else
                            {
                                qDebug()<<"新文件下载完毕!!";
                            }
                            //更改版本配置文件
                            this->writeinifile(QVariant(aa.key()).toString(),QVariant(aa.value()).toString());
                        }else{
                            //下载不成功!! 配置文件不变 下次继续更新
                            qDebug()<<"下载失败!!";
                            failfiels.push_back(aa.key());//记录失败的文件
                            //把原来的文件移回来 并删除临时文件夹里的文件
                            if(aa.key()!=QString("YfFf.exe")){
                                this->copytoanother(QString("DownTemp/%1").arg(QVariant(aa.key()).toString()),QString("SDLL/").append(QVariant(aa.key()).toString()));
                            }else
                            {
                                this->copytoanother(QString("DownTemp/%1").arg(QVariant(aa.key()).toString()),QVariant(aa.key()).toString());
                            }
                            
                            //源版本号不变!!
                            qWarning()<<"部分文件更新失败!下次次启动会自动更新!!";
                        }
                        //if(ok)删除临时文件夹的文件并且修改版本号 不成功 就从临时文件夹挪回来 记录失败文件
                        i++;
                        --updatefilenumber;
                        ui->label_2->setText(QString("剩余:%1").arg(QString::number(updatefilenumber)));
                    }
                }
            }
            qDebug()<<failfiels; //要不要记录版本号了啊
            ui->label_3->setText(QString("更新完毕!成功%1个!失败%2个!").arg(QString::number(number-failfiels.size())).arg(failfiels.size()));
            exit(0);
        }
    }else
    {
        qWarning()<<"群发更新出错!!返回数据有误!!"<<jsonerror.error<<jsonerror.errorString();
        exit(0);
        
    }
}
void MainWindow::copytoanother(const QString &source, const QString &destination)
{
    //根据文件路径来复制文件到指定临时文件夹!避免更新不成功的时候原来的也不能用了
    QDir newdir;
    bool checksource=newdir.exists(source);
    QFileInfo info(destination);
    
    if(checksource)
    {
        bool check=newdir.exists(info.path());
        QString   source1=QDir::toNativeSeparators(source);
        if(check)//判断复制到的文件夹是否存在 不存在的话就重新创建一个
        {
            if( QFile::copy(source1,destination))
            {
                qDebug()<<QString("复制%1成功!正在删除源文件!").arg(source);
                if( QFile::remove(source1)){qDebug()<<"删除成功!";}
            }
            qDebug () <<"新文件被转移到"<<info.path();
        }
        else
        {
            newdir.mkdir(info.path());
            if( QFile::copy(source1,destination))
            {
                qDebug()<<QString("复制%1成功!正在删除源文件!").arg(source);
                if( QFile::remove(source1)){qDebug()<<"删除成功!";}
            }
            qDebug () <<"新文件被转移到"<<info.path();
        }
    }
    else
    {
        qWarning () <<"被复制源文件不存在"<<source;
    }
    
}
bool MainWindow::downfiles(QString url,QString downfilename)
{
    qDebug()<<"正在下载文件!!";
    //群发程序和群发所需的dll不在同一个文件夹 下载和转移的时候对路径要进行转换
    if(downfilename.contains(".dll"))
    {
        downfilename=QString("SDLL/").append(downfilename);
    }
    
    //url 为下载更新文件的地址 downfilename为下载后的图片的名字!
    QNetworkAccessManager *downmanager=new QNetworkAccessManager(this);
    QEventLoop postevent;//设置循环事件
    QNetworkReply *getcheckeddata=downmanager->get(QNetworkRequest(QUrl(url)));
    connect(getcheckeddata,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(updateprogressBar(qint64,qint64)));
    QObject::connect(getcheckeddata,SIGNAL(finished()),&postevent,SLOT(quit()));
    postevent.exec();
    
    if(getcheckeddata->error()==QNetworkReply::NoError)//先判断是不是有错返回
    {
        QByteArray allfiledata=getcheckeddata->readAll();
        // qDebug()<<allfiledata;
        //写入文件
        QFile file(downfilename);
        if (!file.open(QIODevice::WriteOnly))
        {
            return false;
        }
        file.write(allfiledata);
        file.flush();
        file.close();
        // qDebug()<<"文件保存成功!!";
        delete getcheckeddata;
        return true;
    }else
    {//有错的处理!!
        delete getcheckeddata;
        return false;
    }
}
void MainWindow::writeinifile( QString name, QString verson)
{
    qDebug()<<"正在修改配置文件!";
    QSettings addnewfiles("Sdup.yanxuetao", QSettings::IniFormat);
    QTextCodec *codec = QTextCodec::codecForName("gb2312");
    addnewfiles.setIniCodec(codec);
    name==QString("CheckUrl")?addnewfiles.beginGroup("Url"):  addnewfiles.beginGroup("Dll");
    
    addnewfiles.setValue(name,verson);
    qDebug()<<name.append("更新完毕!!");
}
void MainWindow::updateprogressBar(qint64 bytesRead, qint64 totalBytes)
{
    ui->progressBar->setMaximum(totalBytes);
    ui->progressBar->setValue(bytesRead);
}
void MainWindow::mousePressEvent(QMouseEvent *event){
    this->windowPos = this->pos();
    this->mousePos = event->globalPos();
    this->dPos = mousePos - windowPos;
}
void MainWindow::mouseMoveEvent(QMouseEvent *event){
    this->move(event->globalPos() - this->dPos);
}
void MainWindow::paintEvent(QPaintEvent *event)
{ 
    QPainter painter(this);  
    painter.drawPixmap(0,0,width(),height(),QPixmap(":/6.jpg")); 
}
void MainWindow::test()
{ 
    QMessageBox::warning(this,QString("testprocess"),QString(QString::number(testprocess->exitCode())));
}
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值