[Qt ] Créer un updater pour son programme

Statut
N'est pas ouverte pour d'autres réponses.

Proggik

Membre
Inscription
22 Août 2013
Messages
53
Réactions
12
Points
2 361
RGCoins
0
Beaucoup d’entre vous aimerais, qu’une fois leur programme terminé, les utilisateurs n’aient pas à devoir se rendre sur un site web pour télécharger une nouvelle version et à l’installer dès qu’une mise à jour à faite, et bien c’est précisément ce que ce tutoriel vous aidera à faire. Avant de commencer, j’aimerais préciser que ce n’ai pas la meilleure méthode si vous avez beaucoup de fichier à mettre à jour mais qu’elle est très bien si la mise à jour ne concerne que le fichier principale ( l’exécutable principal quoi :) )

Avant de commencer il vous faudra un certains nombre d’éléments :

  • Un serveur FTP ( pour stocker le fichiers mis à jour ainsi qu’un fichier texte )
  • Qt ( 4.8 dans cet exemple )
  • Un compilateur ( MinGW 4.4 dans cet exemple )
Pour le serveur FTP, si vous n’en avez pas, vous pouvez vous en procurer un gratuitement en vous rendant sur et en vous créant un site web ( qui vous fournira un accès FTP ). Pour Qt, si vous ne l’avez pas encore installé ou configuré, je vous invite à suivre .

Vous êtes fins prêt à développer votre updater :)

Introduction
Tout d’abord, définissons ce que nous allons coder :

  • Une application principale ( qui devrais être mis à jour, le l’appellerais » application » tout au long du tutoriel )
  • Une application secondaire, qui aura pour but de mettre à jour l’application principale ( je l’appellerais » updater » tout au long du tutoriel )
L’application aura un bouton, qui aura pour but de vérifier si une mise à jours est disponible, rien de plus pour cet exemple.

L’updater, quant à lui, sera seulement doté d’une barre de progression pour suivre l’avance du téléchargement.

Dans la pratique, l’objectif sera de lancer l’application, d’appuyer sur un bouton pour vérifier si le logiciel est à jours en récupérant le contenue d’un fichier texte sur le FTP et de comparer la valeur avec une variable local ( propre au logiciel ), et, le cas échéant, télécharger la mise à jour stocker sur le serveur FTP.

Mise en place
Application
Pour commencer, et comme indiquer, nous allons, créer notre l’application que l’on souhaite mettre à jour. Une fois terminé, elle ressemblera à sa :

tutoriel_updater_1.png

Comme vous pouvez le voir, j’ai positionné un bouton qui nous permettra de faire la mise à jours ainsi qu’un label, pour bien montrer que le logiciel a bien été mis à jours, rien de superflus pour ne garder que l’essentiel (non, ce n’est pas une réplique de pub :D )

Niveau code, j’ai crée une classe tuto héritant de QWidget, dont voici le fichier header :

PHP:
#ifndef TUTO_H
#define TUTO_H
#include <QApplication>
#include <QtGui>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QCoreApplication>
#include <QUrl>
class tuto : public QWidget
{
    Q_OBJECT
    public:
        tuto();
    protected:
        QPushButton *updateSoftware;
        QNetworkReply *reply;
        QString version; // Version actuel
        QString versionNew; // Version de la nouvelle version si elle existe
        QLabel label;
    public slots:
        void updater(); //Slot de mise à jour
};
#endif // TUTO_H

Rien de bien intéressant, passons donc au fichier .cpp :

PHP:
#include "tuto.h"
tuto::tuto() : QWidget()
{
    setFixedSize(225,75);
    setWindowTitle("Application | Tuto");
    version = "1.0"; //Mettez ici la version actuel de votre application
                    //C'est ce string qui sera comparer pour déterminer s'il y a bien une nouvelle version.
   
    label.setText("<strong>Version actuel :</strong>" + version);
    updateSoftware = new QPushButton("-- Vérifier la présence de mise à jour --", this);
    QVBoxLayout *VLayout = new QVBoxLayout(this);
    VLayout->addWidget(&label);
    VLayout->addWidget(updateSoftware);
    QObject::connect(updateSoftware,SIGNAL(clicked()),this,SLOT(updater()));
}
void tuto::updater()
{
    QNetworkAccessManager manager;
    reply = manager.get(QNetworkRequest(QUrl("http://site.fr/version.txt"))); // Url vers le fichier version.txt
    QEventLoop loop;
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    updateSoftware->setEnabled(false);
    loop.exec();
    versionNew = reply->readAll();
    updateSoftware->setEnabled(true);
    if (version != versionNew)
    {
        QProcess *qUpdater = new QProcess(this);
        qUpdater->start("updater.exe");
        close();
    }
    else
    {
        QMessageBox::information(this,"Logiciel à jour", "Aucune mise à jours trouvée.");
    }
}

Détaillons tous cela : pour commencer, j’ai déclaré un QString version qui aura pour but de contenir la version actuelle du logiciel, afin de pouvoir être comparé avec la valeur contenue dans le fichier version.txt qui sera téléchargé plus tard. J’ai ensuite connecté le SIGNAL clicked() de mon bouton au SLOT updater() de ma fenêtre.

Ce SLOT updater() va nous permettre de vérifier s’il existe une nouvelle version sur le serveur FTP. Je ne vous refais pas un tutoriel sur l’utilisation de la classe QtNetwork , puisqu’un très bon tutoriel existe déjà .

Nous lançons donc une requête avec comme paramètre l’url de notre fichier version.txt que nous stockons dans notre QString versionNew. De là, on fais une comparaison avec les valeurs de version et versionNew : si les valeurs diffères, on lance notre updater et on quitte l’application, sinon, on informe l’utilisateur qu’aucune nouvelle version n’est disponible grâce à une boite de message.

Voilà, la réalisation de l’application s’arrête ici. Passons maintenant à notre updater.

Updater
Notre updater sera tout simple, une fenêtre contenant une barre de progression afin de tracker la fin du téléchargement, c’est amplement suffisant. Bien sûr, libre à vous de rajouter/personnaliser votre updater comme vous le voulais, j’essaye ici de minimiser les éléments graphiques afin de ne pas encombrer le code. ( Aucun screenshot, sa n’a aucune intérêt ).

Niveau code, voilà le contenu du fichier d’en-tête ( basique ) :

PHP:
#ifndef UPDATERFEN_H
#define UPDATERFEN_H
#include <QApplication>
#include <QtGui>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QCoreApplication>
#include <QUrl>
class UpdaterFen: public QWidget
{
    Q_OBJECT
    public:
        UpdaterFen();
    private:
        QProgressBar *progression;
        QNetworkReply *reply;
        QNetworkAccessManager manager;
    public slots:
        void progressionTelechargement(qint64 bytesReceived, qint64 bytesTotal);
        void enregistrer();
};
#endif // UPDATERFEN_H

Une petite remarque que j’aimerais faire, c’est que je ne gère pas les erreurs, ces qui est très mal je vous l’accorde, mais j’ai eu quelques problèmes, je préfère donc vous livrer quelques chose que j’ai testé. Le fichier .cpp maintenant. Voilà d’abord le constructeur :


Ici, nous créons la requête qui va nous permettre de récupérer la nouvelle version de notre application depuis le serveur FTP. On connecte ensuite notre SIGNAL finished() de notre réponse au SLOT enregistrer() de notre application, ainsi que le SIGNAL downloadprogress() de notre réponse au SLOT progressionTelechargement() de notre application, qui va nous permettre de faire augmenter notre barre de progression en fonction du nombres de bytes téléchargés.

Voilà notre SLOT progressionTelechargement() :

PHP:
void UpdaterFen::progressionTelechargement(qint64 bytesReceived, qint64 bytesTotal)
{
    if (bytesTotal != -1)
    {
        progression->setRange(0, bytesTotal);
        progression->setValue(bytesReceived);
    }
}

Ainsi que notre SLOT enregistrer() :

PHP:
void UpdaterFen::enregistrer()
{
    reply->deleteLater();
    QFile lastversion("application.exe");
   
    if ( lastversion.open(QIODevice::WriteOnly) )
    {
        lastversion.write(reply->readAll());
        lastversion.close();
        QMessageBox::information(this, "Fin de téléchargement", "Téléchargement terminé !");
    }
    close();
}

Ici, on créer un QFile qui va représenter notre fichier sur le disque dur, puis on test si l’ouverture du fichier se déroule bien, pour ensuite l’écrire sur le disque. Une fois cela de fais, on ferme le fichier est la réponse du serveur se détruit. Puis on informe l’utilisateur que le téléchargement est terminé. Enfin, si vous vouliez, par exemple, écrire le fichier dans un dossier plus « haut » dans l’arborescence, il vous suffirais de faire précédé le nom de votre application par ../ lors de sa création.

Voilà, c’est la fin de ce tutoriel, n’hésitez pas à me faire vos retours, à m’indiquer si le tutoriel comporte des erreurs, que ce soit orthographique ou technique, et puis, j’espère qu’il vous sera utile ;)
 
Yop ! Toi aussi tu a utiliser Qt ? :) J'adorais ce logiciel, hyper pratique, hyper complet, génialissime ! Le seul truc embêtant sont les librairies à trainer ! :(
Sinon excellent tuto ! :)
 
J'utilise pas tous le framework Qt, j'utilise que les modules dont j'ai besoin donc au final, ya rien à trainer comme dépendance pratiquement ;)
Et merci!
 
J'utilise pas tous le framework Qt, j'utilise que les modules dont j'ai besoin donc au final, ya rien à trainer comme dépendance pratiquement ;)
Et merci!
Oui oui je le sais, moi ce qui me chagrinai, c’était cette dll, le fait quelle soit là ! :) Pour donner ton .exe c’était pas toujours pratique ! :)
 
Après tu peux compiler en statique et n'avoir que ton exécutable à transmettre, et je trouve sa désavantageux parce que quand tu veux mettre à jours ton logiciel ( que sa soit via cette méthode ou via un parsage de fichier XML ), t'es obligé de retélécharger un exécutable super lourd, c'est pour sa qu'il est préférable de compiler dynamiquement et de faire un installeur qui se chargera de décompresser les dépendances pour l'utilisateu, AHMA :)
 
Oui je connaissait cela ! :) C'est pour cela, que j'ai arrête Qt et je suis passer a C# avec Visual Studio ! :)
 
Ah ouais mais c'est pas les même perf C# et C++, enfin, les goûts ne se discutes pas, si tu préfère, c'est tant mieux ;)
Mais même pour un programme en C#, ce tutoriel reste valide ( tu peux faire ton programme en C# et lancer l'updater fait en C++ )
 
Je sais bien, ce sont des langages communs ! :) Moi aussi au début, je n'utilisait que Qt, par la suite on m'a convaincu de faire de C# ! :)
 
Passer du C++ au C# ?! Sériesement ? Passer du meilleur langage à un langage qui utilise une machine virtuelle ? Mais OMAGAD !
En plus vive le leech, le tuto vient de Funky-Emu (écrit par SgT-Fatality).
 
Non c'est faux renseignes-toi avant.
Et puis bien de déterrer un sujet d'il y a un an ! C'est cool !
 
Merci du tuto :) c'est mieux de mettre un systeme de mise à jour que de tout le temps upload une nouvelle vesion du logiciel ou que les autres telecharge à chaque fois la nouvelle version pour se retrouver avec 400 version x)
 
Statut
N'est pas ouverte pour d'autres réponses.
Retour
Haut