Permettre la mise à jour automatique de ses programmes
Un article de LaPageDuJour.
Une des plus grosses avancées informatique de ces cinq dernières années consiste à développer et vendre des logiciels plus rapidement mais dont on sait qu'on devra les mettre à jour. Cela implique que l'on doit prévoir ses programmes pour pouvoir être mis à jour par le réseau (la plupart du temps Internet).
Si vous êtes amenés à faire des programmes qui seront distribués à des personnes. A moins d'être sur que votre programme est parfait et qu'il n'évoluera pas ou que vous serez près à réaliser la mise à jour des programmes poste par poste, il vous est nécessaire de réaliser un système de mise à jour.
Sommaire |
[modifier] Rapide théorie
Pour qu'un programme puisse être mis à jour il faut :
- Que l'on ai les droits d'écriture dessus
- Que ce programme ne soit plus en fonctionnement, car :
- Il peut ne pas être totalement chargé en mémoire
- Le système peut empêcher l'écriture d'un fichier éxécuté
- Qu'une erreur dans le programme n'empêche pas ses prochaines mise à jour
Donc :
- Il faut créer une application à part
- Il faut que cette application ne soit pas lancée en même temps que l'application à mettre à jour
Ceci mène à un type de solution simple :
- Il faut réaliser une application minimale de mise à jour à part qui :
- Ne soit pas faillible, elle doit fonctionner quelques soit les situations
- Doit elle même être mise à jour le moins possible
- Doit être capable d'attendre que l'application principale se quitte
- L'application principale au moment où elle décide de lancer la mise à jour doit ainsi :
- Fermer l'essentiel de ses ressources
- Lancer l'application secondaire en lui précisant un délais avant de commencer les opérations (par exemple 5 secondes)
- Quitter
Dans ce modèle, on pourra aussi demander à l'application de mise à jour de relancer l'application principale.
[modifier] Solution pratiques
[modifier] RSync
RSYNC est une application et un protocole qui permet de synchroniser des répertoires. C'est une solution idéale pour réaliser ce type de traitement. Il permet d'échanger une quantité minimale d'information pour permettre à l'utilisateur de posséder exactement la même version que celle présente sur le serveur.
Avantages :
- Consommation de bande passante minimale
- Multiplateforme
Inconvenients :
- Traitement de hashage souvent consommateur de ressources pour le client
- Application relativement lourde
- Ne permet pas de traitement spécifique (il faudra faire une autre application en plus)
- Nécessite un serveur rsync
[modifier] CVS / SVN
CVS est un système de développement collaboratif. Il peut être utilisé pour mettre à jour un programme, mais il a été étudié pour mettre à jour avant tout des données textuelles. SVN permet de faire les même choses en corrigeant quelques défauts de CVS.
Avantages :
- Multiplateforme
- Faible consommation de bande passante (mais plus importante que rsync)
- Gestion claire du suivi de versions
Inconvenients :
- Pas adapté aux fichiers binaires
- Relativement lent
- Application relativement lourde
- Nécessite un serveur CVS/SVN
- Ne permet pas de faire des traitements nativement
- Permet de revenir en arrière (vous ne souhaitez pas forcément ça)
[modifier] Solution personnelle
On peut aussi décider de créer une petite solution personnelle. Dans notre cas, nous la réaliserons en C# et nous réaliserons un système minimale de mise à jour par taille de fichier (ça suffit dans l'essentiel des cas).
Même si je m'inspire d'un programme de mise à jour que j'ai réellement créé, j'ai simplifié volontairement le code source pour que celui ci soit aussi simple à comprendre que possible. Il n'y a pas de gestion d'actions avancées, pas de gestion de la ligne de commandes, pas de gestion de hashage de fichier.
Notez que si vous voulez faire un système de mise à jour aussi fiable que possible, essayez d'en réduire au minimum, quitte à limiter les fonctionnalités avancées. Faire un système de mise à jour tellement avancé que l'on est plus capable d'en comprendre le fonctionnement quelques mois plus tard est une très mauvaise idée (concrètement à un programme classique).
On va définir par exemple un fichier texte spécifiant les fichiers de l'application à mettre à jour :
programme.exe,280583 images/toto.png,20000 images/tata.png,10000 sons/welcome.wav,50305
Et le programme correspondant :
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Threading; using System.Net; namespace updater { class Program { // La méthode de téléchargement public static Boolean Download(String url, String destinationFile) { int BUFFER_SIZE = 8192; WebRequest requete; WebResponse reponse; try { requete = HttpWebRequest.Create(url); reponse = requete.GetResponse(); Stream lecture = reponse.GetResponseStream(); Stream ecriture = new FileStream(destinationFile, FileMode.Create); int n = 0; Byte[] donnees = new Byte[BUFFER_SIZE]; do { n = lecture.Read(donnees, 0, BUFFER_SIZE); ecriture.Write(donnees, 0, n); } while (n > 0); ecriture.Close(); lecture.Close(); } catch { return false; } return true; } // Le programme static void Main() { // On attend que le papa fasse dodo Thread.Sleep( 5000 ); String baseUrl = "http://update.monsite.com/"; // On télécharge le fichier de mise à jour (on aurait pu le lire dans un flux, mais ça simplifie l'exemple) if ( ! Download( baseUrl+"update.txt", "update.txt" ) ) Application.Exit( 10 ); StreamReader flux = new StreamReader( "update.txt" ); while ( ! flux.EndOfStream ) { String [] split = fichier.ReadLine().Trim().Slit(','); String fichierNom = split[0]; UInt32 fichierTaille = UInt32.Parse( split[1] ); // Si le fichier existe déjà ... if ( File.Exists( fichierNom ) ) { // Et qu'il n'a pas la même taille que celle qu'il devrait avoir if ( (new System.IO.FileInfo(fichierNom)).Length != fichierTaille ) // On le télécharge Download( baseUrl+fichierNom, fichierNom ); } // Sinon (s'il n'existe pas), on le télécharge else Download( baseUrl+fichierNom, fichierNom ); } flux.Close(); } } }
Même si c'est difficile à croire, ce programme de mise à jour est fonctionnel et pourra déjà vous rendre de nombreux services.
Avantages :
- Ce programme est léger, il pèse moins de 5 Ko en C# .Net Compact compilé en mode Release
- Ce programme est fiable
Inconvénients :
- Impossible de tester le contenu des fichiers par un hash, un fichier BMP modifié ne sera pas mis à jour à moins de le trafiquer pour en modifier la taille (sans en modifier le contenu).
- Les capacités du programme sont très limitées
Si vous voulez aller plus loin, vous devriez tout de suite :
- Permettre le passage d'arguments par la ligne de commande pour permettre de configurer certaines options
- Passer par des fichiers intermédiaire pour le téléchargement pour qu'en cas de problème vos fichiers ne soient pas supprimés
- Permettre de mettre à jour le système de mise à jour en :
- Faisant télécharger l'application de mise à jour dans un fichier intermédiaire
- Faisant déplacer le fichier intermédiaire vers la nouvelle application de mise à jour au démarrage du programme principal
- Permettre des opérations spéciales comme :
- Ne télécharger un fichier que s'il n'existe pas (c'est à dire ne pas le re-télécharger s'il a été modifié)
- Exécuter un fichier s'il a été mis à jour
- Supprimer un fichier (comme les fichiers d'index dans certains programmes)
- Renommer un éventuel fichier
- Réaliser des backups des fichiers mis à jour
- Permettre la modification du registre système à partir de fichiers téléchargés
- Ajouter le hashing de fichier (mais il peut être intéressant de ne l'activer que pour certains fichiers pour éviter la sur-consommation de ressources)
[modifier] Le déclenchement des mises à jour
Si vous voyez maintenant différentes façon de réaliser une mise à jour, il faut maintenant être capable de choisir quand on va réaliser des mise à jour :
- Selon les désir de l'utilisateur :
C'est une bonne solution pour un produit qui évolue peu. La mise à jour se fera quand l'utilisateur en ressentira le besoin (par exemple quand il aura l'impression d'être victime de bugs). Il faut accepter dans ce cas là d'avoir des programmes qui tournent sur des versions différentes.
- A intervalle réguliers :
C'est sans doute la solution la plus sage. Vous pouvez vérifier la présence de mise à jour à chaque démarrage du programme, à chaque fermeture du programme ou tous les mois, toutes les semaines.
- Par déclenchement distant :
Si vous avez réalisé une application qui fonctionne par le réseau, vous pouvez faire en sorte que votre serveur signale au client qu'il doit se mettre à jour. C'est sans doute la meilleure solution si vous souhaitez avoir un contrôle précis de votre solution. Cependant, il vaut mieux faire en sorte que le programme de mise à jour fonctionne même si le système de déclenchement des mise à jour par le réseau ne fonctionne plus.
[modifier] Problématique des versions
Si vous êtes amené à créer une logiciel, comme pour n'importe quel produit vous allez devoir définir certains "politiques", c'est à dire certaines règles qui régissent ceux que vous allez faire ou ne pas faire. Quelle sera donc votre politique concernant les versions et la mise à jour des logiciels ?
Parmis les questions que vous devriez vous poser, voici une petite liste :
- Allez vous permettre aux applications anciennes (dépassées) d'interagir avec votre système ou allez vous imposer l'utilisation de la dernière version du programme ?
- Permettrez vous la mise à jour et la conversion des fichiers de données des applications, et ce même lorsque la mise à jour saute 2 ou 3 versions ?
Ces questions n'ont pas de réponses simple. Cela dépend aussi du publique à qui s'adresse votre logiciel, s'il est gratuit ou non, si vous faites payer ou non les versions de votre logiciel, si vous faites payer les versions majeur mais pas les mineures (le plus fréquent dans l'industrie).