On ne fait pas de la magie

«Toute technologie suffisamment avancée est indiscernable de la magie.» Arthur C. Clarke

Catégorie : Développement

  • MSI et Windows Installer

    A l’occasion d’une formation Installshield, j’ai rafraichi ma liste d’outils tournant autour de MSI et de Windows Installer.

    Voilà un extrait de la panoplie :

    MAKEMSI est un logiciel freeware qui permet de construire un package MSI à partir d’une description définie dans un fichier XML.

    Dans la même lignée, j’aurais tendance à préférer WiX (Windows Installer Toolkit) qui utilise lui aussi une syntaxe XML pour décrire une installation. Il dispose d’un sous projet Votive pour manipuler ses fichiers avec Visual Studio.

    Advance Installer est un outil de conception d’installation, avec une interface graphique, disponible sous plusieurs éditions. Il existe une édition gratuite qui permet de créer des projets simples.

    Enfin, si Orca vous semble trop rudimentaire ou rébarbatif, vous pouvez utiliser InstEd pour éditer directement vos fichiers MSI.

  • Comment utiliser Installshield pour effacer des fichiers lors d’une installation ?

    Une question récurrente qui m’est posée lors d’interventions sur Installshield concerne la suppression de fichiers présents sur la machine cible au moment de l’installation.

    Il est normal qu’elle soit posée, car la réponse n’apparaît pas de façon évidente dans l’interface du logiciel.

    Si vous souhaitez supprimer des fichiers qui sont présents lors de l’installation, il faut renseigner la table RemoveFile, en vérifiant l’action RemoveFiles est bien présente dans la séquence d’installation.

    Cette table contient contient une propriété DirProperty qui indique le chemin complet du répertoire du fichier à supprimer. InstallMode permet de spécifier si le fichier est effacé lors de l’installation, de la désinstallation ou dans les deux cas.

    EffacerFichierInstallshield1.png

    Le composant indiqué doit bien sur être associé à une fonctionnalité installée pour que l’opération soit exécutée.

    Attention, l »interface graphique d’Installshield ne montre pas la liaison entre le composant et la table RemoveFile. Notamment, si on demande à n’afficher que les nœuds non vide, le composant peut apparaitre comme vide alors que la table RemoveFile fait référence au composant.

    EffacerFichierInstallshield2.png

    Vous pouvez constater que le composant EffaceFichier semble vide alors qu’il est utilisé pour supprimer des fichiers au travers de la table RemoveFile :

    EffacerFichierInstallshield3.png

     

    .

  • Comment utiliser Installshield pour forcer l’installation de fichiers par Windows Installer ?

    Lors des prestations ou de formations sur Windows Installer ou Installshield, j’ai parfois la question de forcer l’installation de fichiers sans tenir compte des caractéristiques de taille ou de version de ceux qui seraient éventuellement déjà présents.

    C’est une possibilité que vous pouvez indiquer dans la fenêtre de propriété d’un fichier, en cochant l’option Always Overwrite.

    EcrasementFichierInstallshield.png

    Que fait Installshield lorsque cette option est cochée ? Il inscrit tout simplement la valeur 65535 dans la colonne Version de la table File. De cette façon, les mécanismes normaux de Windows Installer forcent l’installation du fichier, quelle que soit la version du fichier éventuellement installée sur le système.

    La difficulté de cette méthode est qu’il faut passer en revue tous les fichiers de tous les composants et cela peut devenir une tâche rédhibitoire s’ils sont nombreux.

    Pour éviter cela, à partir de Windows Installer 4, il est possible d’utiliser la propriété REINSTALLMODE ou l’option /f de la ligne de commande de msiexec.

    Cette option est normalement utilisée en combinaison avec la propriété REINSTALL, mais Windows Installer la prend aussi en compte lors d’une installation. En spécifiant la valeur a, tous les fichiers sont copiés, indépendamment des versions. Vous pouvez tout simplement l’indiquer sur la ligne de commande ou l’incorporer à votre installation en utilisant le Property Manager ou encore en modifiant la table Property avec le Direct Editor.

    Attention, il peut y avoir des effets de bords. Par exemple, si votre installation contient des modifications du registre, celles ci ne sont pas effectuées si REINSTALLMODE ne contient que la valeur a. Il faut ajouter les valeurs u ou m pour que le registre soit modifié !

  • Ecrire un plugin jQuery pour centrer des éléments

    Lorsqu’on utilise jQuery, on peut écrire des fonctions javascript classiques qui font simplement appel à jQuery pour effectuer le traitement souhaité.

    L’ennui avec ces fonctions est que leur utilisation est plus délicate que l’utilisation de jQuery.

    Par exemple, prenons le cas d’une fonction qui permet de centrer un élément. Cette fonction peut s’écrire ainsi :

    function centreElement(element) {
    $(element).css({
    'top': (($(window).height() - $(element).height()) / 2) + $(window).scrollTop(),
    'left': (($(window).width() - $(element).width()) / 2) + $(window).scrollLeft()
    });
    }

    Cette fonction peut être appelée sur n’importe quel élément, de cette façon centreElement('#image1'). Mais que se passe t-il si on veut centrer horizontalement plusieurs éléments images ?

    Il suffit de modifier un peu cette fonction pour ne centrer qu’horizontalement. Par contre, il faut exécuter une boucle, par exemple avec la fonction each de jQuery, pour appeler autant de fois que nécessaire cette fonction. Une solution plus élégante peut être d’écrire son propre plugin jQuery, c’est à dire, tout simplement, une fonction personnelle qui se comporte comme une fonction intégrée de jQuery.

    Voilà la façon dont on pourrait écrire un tel plugin :

    (function($) {
    $.fn.centreElement = function() {
    this.each(function() {
    var $e = $(this);
    $e.css({
    'left': (($(window).width() - $e.width()) / 2) + $(window).scrollLeft()
    });
    });
    return this;
    };
    })(jQuery);

    Un plugin jQuery nom est tout simplement une fonction définie avec $.fn.nom. Pour éviter tout télescopage avec d’autres bibliothèques installées, on utilise une fonction anonyme qui reçoit un paramètre $, et on appelle cette fonction avec jQuery :

    (function($) {

    // ici, $ représente jQuery sans aucun risque de télescopage avec une autre bibliothèque

    })(jQuery);

    Il suffit maintenant de définir une fonction anonyme pour $.fn.centreElement.
    Cette fonction doit pouvoir être chainée avec d’autres appels de fonction jQuery et pour cela, elle doit renvoyer l’objet this fourni par jQuery.
    Elle doit également exécuter son traitement sur chaque noeud référencé par jQuery, ce que l’on peut réaliser avec la fonction each().
    Voilà donc la structure que doit avoir tout plugin jQuery :

    $.fn.centreElement = function() {
    this.each(function() { // boucle générique sur chacun de éléments avec la fonction each()
    // code spécifique au plugin écrit
    });
    return this; // valeur de retour pour pouvoir effectuer le chainage
    };

    Et il ne reste plus, pour effectuer le centrage, qu’à reprendre ce que nous avions écrit dans la première fonction, en enlevant le top :

    var $e = $(this);
    $e.css({
    'left': (($(window).width() - $e.width()) / 2) + $(window).scrollLeft()
    });

    Notre plugin permet maintenant d’écrire des instructions comme :

    $('img').centreElement().show();

    Cet exemple est parfois employé comme exercice de cours jQuery

  • GOTO : Fortran, C, C++, Java, C# et PHP

    Lors des formations sur les langages de développement que je réalise, il y a toujours un moment fort lorsque les stagiaires sont des développeurs : la discussion sur le GOTO !

    Discussion dont la longueur est très variable suivant le langage. En Fortran 77, il est impossible de quitter une boucle DO sans utiliser le GOTO. Ce n’est que dans des versions plus récentes de la norme que sont apparus CYCLE et EXIT.

    Mais pourquoi des langages plus modernes, comme CC++ ou C#, continuent-ils à disposer d’une instruction GOTO ? Et pourquoi la dernière version de PHP (5.3) a-t-elle introduit cette instruction qui n’existait pas dans les versions précédentes ?

    Les critiques sur le GOTO datent d’un article de 1968 Go To Statement Considered Harmful, écrit par Dijkstra. Vous trouverez dans l’article Goto Perl l’histoire détaillée de cet article et la polémique qui en a résulté. Polémique qui a dégénéré en réponses dogmatiques : « GOTO c’est mal » et « il ne faut pas utiliser GOTO ».

    Certes, mais comment résoudre un problème d’algorithmique courant : la sortie de deux boucles imbriquées ? Pour y répondre, j’ai parfois vu des constructions alambiquées, utilisant des variables logiques, transformant des boucles à nombres d’itération connus (par exemple un parcours de matrice suivant les lignes et les colonnes) en boucles WHILE incompréhensibles demandant trois lectures pour commencer à entrevoir le traitement effectué.

    Or, que reproche-t-on à GOTO ? De conduire à du code incompréhensible à un humain …

    Le principal cas où il faut utiliser le GOTO dans des langages comme C, C++, C# ou PHP est la rupture de boucle. Ces quatre langages proposent les instructions break et continue pour quitter une boucle. Mais ils ne proposent pas la syntaxe break n du Java qui permet de quitter plusieurs boucles imbriquées. D’où la nécessité de disposer de l’instruction GOTO.

    Suivant les cas, il peut également être légitime d’utiliser GOTO lorsqu’une erreur ou un évènement externe à l’algorithme se produit, lorsqu’on ne peut pas ou on ne veut pas utiliser d’exception.