Paquet et déploiement
Un domaine du développement logiciel étant souvent négligé est la façon de déployer l'application. Construire un programme d'installation peut transformer votre application d'un utilitaire amateur en un outil professionnel. Cette page explique comment créer un programme d'installation Windows pour à peu près n'importe quel type d'application .NET.
L'outil d'installation décrit dans cette page est l'ensemble d'outils Windows Installer XML (WiX). Cet ensemble d'outils, disponible via la boîte de dialogue Extensions et mises à jour (Extensions and Updates), vous permet de spécifier le contenu et les fonctionnalités du paquet d'installation via des fichiers XML. Et bien que l'idée d'utiliser des fichiers XML puisse sembler intimidante au départ, elle fournit toutes les fonctionnalités faisant partie des projets d'installation de Visual Studio dans les versions antérieures de Visual Studio. En fait, il offre encore plus de fonctionnalités. Et bien que l'ensemble d'outils soit étroitement intégré à Visual Studio, il est également disponible via une interface de ligne de commande, ce qui le rend tout à fait adapté à une utilisation dans un processus de génération.
La sortie de WiX est, en fin de compte, un paquet Windows Installer pouvant être livré à quelqu'un souhaitant installer votre application. En règle générale, il s'agit d'un fichier .MSI (Microsoft Installer), bien que WiX prenne également en charge les fichiers de correctifs (.MSP), les modules d'installation (.MSM) et les transformations (.MST). Sachez que toutes les applications .NET ne peuvent pas être installées à l'aide d'un programme d'installation Windows. Les applications fournies via le Windows Store, par exemple, entrent dans cette catégorie, tout comme les applications ClickOnce. En outre, vous ne pouvez pas déployer d'applications Web sur Azure à l'aide de MSI.
Ensemble d'outils XML du programme d'installation de Windows
Le WiX (abréviation de l'anglicisme Windows installer XML) est une boîte à outils se composant d'un certain nombre de composantes différents, chacun ayant son propre objectif. Et parce que les geeks aiment trouver de l'humour dans les noms, les composantes portent le nom d'éléments liés aux bougies. (WiX se prononce «mèches» comme dans «la bougie a quatre mèches».) Les composantes sont :
- Candle : le compilateur convertissant les documents XML en fichiers objets contenant des symboles et/ou des références à des symboles.
- Light : L'éditeur de liens prenant un ou plusieurs fichiers objets et résout les références de symboles. La sortie pour Light inclut également généralement le fichier MSI ou MSM empaqueté.
- Lit : un outil pouvant combiner plusieurs fichiers objets (tels que ceux produits par Candle) dans un nouveau fichier objet pouvant ensuite être traité par Light.
- Dark : un décompilateur examinant les fichiers MSI et MSM existants et génère les documents XML représentant le paquet d'installation.
- Tallow/Heat : Tallow génère un code de liste de fichiers WiX en parcourant une arborescence de répertoires. Le fragment de XML produit peut être incorporé avec d'autres fichiers source WiX par Candle. Heat est un outil plus récent effectuant une tâche similaire, quoique de manière plus générale.
- Pyro : Un outil utilisé pour créer des fichiers de correctif (fichiers .msp) sans avoir besoin du SDK Windows Installer.
- Burn : Un outil agissant comme un chaîneur d'amorçage/d'installation. L'idée de base est de permettre aux paquets de spécifier des dépendances, et le Burn coordonne l'installation des prérequis avant l'installation du paquet principal.
Pour commencer à créer un paquet WiX, vous devez installer la boîte à outils dans votre environnement de développement. Vous pouvez installer l'ensemble d'outils WiX en accédant aux extensions et mises à jour des outils. Entrez ensuite WiX Toolset dans la zone de recherche dans le coin supérieur droit de la boîte de dialogue s'affichant. Lorsque l'extension WiX Toolset Visual Studio 2017 apparaît dans la section centrale, cliquez sur le bouton Télécharger (Download) pour démarrer l'installation. Vous devrez redémarrer Visual Studio pour terminer le processus. En plus de l'extension, incluant les modèles de projet, vous devrez installer les outils de création Wix. Vous pouvez trouver les fichiers d'installation actuels de WiX sur https://wixtoolset.org/docs/releasenotes/.
Construire un installateur
Pour créer un programme d'installation avec Visual Studio 2017, vous devez ajouter un projet supplémentaire à l'application que vous souhaitez déployer. L'image suivante montre les modèles de projet de configuration et de déploiement disponibles inclus avec WiX :
Le projet de configuration ou le projet d'amorçage peuvent être utilisés pour la plupart des applications autonomes. Cela inclut les applications ou les services Web ASP.NET. La différence entre les deux est le format de la sortie, le projet d'amorçage produisant un fichier .EXE, tandis que le projet d'installation crée un fichier .MSI. Si vous souhaitez créer un programme d'installation étant intégré dans un programme d'installation plus important, vous pouvez créer un module de fusion. Vous pouvez également utiliser le projet Setup Library pour créer une composante d'installation (wixlib), une fonctionnalité d'installation que vous pouvez utiliser dans plusieurs paquets d'installation, de la même manière que vous utilisez des assemblys dans plusieurs applications.
A la création du projet, un seul fichier apparaît dans le designer. Pour être juste, le projet d'installation contient d'autres fichiers, mais le fichier Product.wxs est le point de départ et le coeur du paquet d'installation. Commencez donc par jeter un oeil au contenu. La figure suivante montre le fichier par défaut :
Vous pouvez remarquer que le fichier est divisé en trois éléments principaux :
- Product : Cette section décrit les informations fondamentales sur l'installation. Cela inclut le fabricant, les composantes à inclure, le support à utiliser et d'autres détails utilisés pour créer le fichier MSI ou MSM.
- Fragment/Directory : Cette section décrit la disposition des dossiers placés sur la machine cible. Vous remarquerez peut-être que la valeur par défaut semble être organisée de manière hiérarchique. Ce n'est pas une coïncidence mais une fonction de la nature déclarative de WiX. La hiérarchie dans ce fragment représente la hiérarchie du répertoire créé sur le système de fichiers cible.
- Fragment/ComponentGroup : cette section décrit les fonctionnalités à installer. Le groupe de composantes définit les fichiers composant une fonction. Grâce à un fragment encore à voir, les fichiers du groupe de composantes sont cartographiés sur la structure de répertoires. Et dans le fragment Product, les groupes de composantes composant le produit sont identifiés.
Pour commencer, considérez l'élément Product. Comme déjà mentionné, cet élément décrit le logiciel en cours d'installation. Dans l'élément Product, il y a un certain nombre d'attributs qui doivent être définis - ou au moins modifiés par rapport à la valeur par défaut.
Il existe deux GUID liés aux produits. L'attribut Id est utilisé pour identifier de manière unique votre paquet. Le produit WiX vous permet de spécifier un astérisque comme valeur GUID, auquel cas le GUID est généré dans le cadre du processus de compilation. Pour le Product, vous devez en profiter car chaque installation sera différente et nécessitera donc un identifiant unique.
Le deuxième GUID est UpgradeCode. Cette valeur est utilisée si vous créez un paquet d'installation de mise à niveau - en d'autres termes, pour le paquet d'installation de la deuxième version ou des versions ultérieures de votre produit. Chaque mise à niveau doit faire référence au code de mise à niveau, donc contrairement à l'attribut Id, cette valeur sera la même pour chaque version de votre produit. En tant que tel, vous devez définir la valeur de l'attribut sur un GUID que vous générez.
Les quatre autres attributs devant être définis concernent davantage l'interface utilisateur et l'expérience du processus d'installation. L'attribut Name est le nom du produit. Il s'agit de la valeur s'affichant lorsque vous consultez la partie Programmes et fonctionnalités (Program and Features) du Panneau de configuration (Control Panel). L'attribut Language est l'identificateur de culture pour cette installation. La valeur par défaut de 1033 est l'anglais américain. L'attribut Version est la version du produit étant installé et est dans le format typique pour un numéro de version. Enfin, l'attribut Manufacturer définit l'organisation produisant le produit (fabricant).
L'élément Product comporte un certain nombre de sous-éléments fournissant des détails supplémentaires sur l'installation. L'élément MajorUpgrade peut déterminer l'action à entreprendre lorsqu'une application est mise à niveau vers une version plus récente. Les actions possibles incluent la désinstallation de l'ancienne version et l'installation de la nouvelle, le remplacement des fichiers ou une action personnalisée.
L'objectif de l'élément MediaTemplate indique la taille et le format du support sur lequel le paquet d'installation sera placé. En fait, via WiX, vous pouvez spécifier dans quel composant multimédia (comme un disque DVD) un fichier particulier sera placé. Le MediaTemplate par défaut, cependant, est généralement suffisant car il inclut les valeurs créant un seul fichier.
L'élément restant dans le produit décrit la fonctionnalité (ou les fonctionnalités) incluses dans le paquet d'installation. Une fonctionnalité dans le langage WiX est une collection d'éléments de déploiement destinés à être installés en tant qu'unité atomique. Cela peut être aussi simple qu'un fichier par fonctionnalité, ou il peut y avoir plusieurs fichiers dans une seule fonctionnalité. Mais peu importe, du point de vue de l'utilisateur, la fonctionnalité est le niveau auquel l'utilisateur a le choix d'installer ou de ne pas installer. En tant que tel, il peut y avoir un ou plusieurs éléments Feature dans le produit.
L'exemple illustré dans l'image précédente n'a qu'une seule fonction. Les attributs sont, pour la plupart, assez typiques. L'Id est un identifiant textuel unique pour la fonctionnalité. Le titre est le nom donné à la fonctionnalité. Il apparaît dans l'interface utilisateur d'installation, il doit donc être convivial. Le Level est utilisé pour imbriquer les Features les unes dans les autres. Pour une fonctionnalité donnée, vous spécifiez les ComponentGroups lui étant associés. Le ComponentGroup indique un bloc particulier d'éléments d'installation. Il peut s'agir d'un assemblage unique ou d'un fichier de configuration ; il peut s'agir d'une collection de fichiers de types différents. Mais l'aspect important de la déclaration est que l'ID du ComponentGroup doit correspondre à un ComponentGroup défini dans l'un des fragments suivants.
La prochain composante majeur d'un fichier WiX est le fragment de répertoire (Directory Fragment). Tout d'abord, notez qu'il ne s'agit pas réellement d'un élément XML de second niveau (c'est-à-dire au même niveau que le produit). Au lieu de cela, c'est un sous-élément d'un fragment. Cette disposition est faite pour permettre aux fragments de répertoire d'être placés dans différents paquets et d'être toujours facilement combinés par l'éditeur de liens lors de la construction du fichier d'installation.
Le contenu du fragment de répertoire est destiné à imiter le système de fichiers existant sur le système cible une fois l'installation terminée. En vous référant à l'image précédente, vous pouvez voir qu'une imbrication à trois niveaux a été définie. Chaque niveau est associé à un identifiant. L'Id peut être signifiant, comme c'est le cas ici. Mais en fin de compte, vous avez la possibilité de cartographier le placement de fichiers individuels dans des répertoires spécifiques en référençant l'Id. L'attribut Name est facultatif ; cependant, si vous envisagez de créer des répertoires là où il n'en existe pas déjà, comme c'est le cas avec l'élément INSTALLFOLDER, il doit être inclus. Dans l'exemple, la valeur par défaut du répertoire créé sous Program Files est le nom du projet.
Le dernier fragment est un ComponentGroup, contenant une référence aux fichiers individuels composant le groupe. L'ID du groupe est important car il doit correspondre à un ID spécifié dans le ComponentGroupRef lorsque les fonctionnalités étaient répertoriées. L'élément ComponentGroup a un attribut Directory ; la valeur de cet attribut spécifie le répertoire où seront placés les fichiers du groupe. La valeur doit correspondre à l'un des ID d'un élément Directory dans le fragment Directory.
Utiliser le Heat pour créer des fragments
Le WiX fournit un outil examinant divers types d'artefacts et crée des fragments WiX en fonction de ceux qu'il trouve. L'outil est connu sous le nom de Heat. Et heureusement, l'un des types d'artefacts qu'il comprend est les fichiers de projet Visual Studio.
Le Heat est un outil utile. Cependant, il s'agit d'un utilitaire de ligne de commande et, en tant que tel, vous devez suivre une étape simple pour l'intégrer à Visual Studio. Plus précisément, il doit être placé dans votre collection d'outils externes. Pour accéder à la collection, sélectionnez Tools/External Tools dans le menu. La boîte de dialogue illustrée dans l'image suivante s'affiche :
Pour ajouter une nouvelle commande, cliquez sur le bouton Add. Pour le nouvel outil, spécifiez un nom de Harvest Project. La commande (qui, sans surprise, est implémentée dans heat.exe) se trouve dans le répertoire WiX Toolset v3.11 sous Program Files ou Program Files (x86) si vous utilisez une machine 64 bits. La valeur Arguments est l'endroit où la magie a lieu. Plusieurs paramètres doivent être définis. Et vous pouvez également utiliser les jetons de projet. Définissez la valeur Argument sur ce qui suit :
project "$(ProjectFileName)" -pog Binaries -ag -template fragment -out $(TargetName).wxs |
Enfin, définissez la valeur du répertoire initial sur $(ProjectDir). Cela permet à l'utilitaire de trouver les fichiers nécessaires à partir de la racine du projet. Assurez-vous que l'option Utiliser la fenêtre de sortie est cochée; puis un dernier clic sur le bouton OK termine le processus de création.
Maintenant que la commande Heat est disponible, vous pouvez l'utiliser. Tout d'abord, dans l'Explorateur de solutions (Solution Explorer), assurez-vous que le fichier du projet en cours avec Harvest est sélectionné. Utilisez ensuite l'option de menu Tools Harvest Project pour analyser le projet en cours. Si tout se passe bien, la fenêtre Sortie (Output) devrait ressembler à l'image suivante :
Si l'opération c'est bien passé, on dirait que rien ne s'est passé. Mais en l'absence de messages d'erreur, l'analyse a réussi.
Le résultat de Harvest de votre projet de cette manière est un fichier .wxs. Plus précisément, il s'agit d'un fichier .wxs portant le même nom que votre projet. Vous pouvez le localiser dans le même répertoire que votre fichier de projet. Pour afficher ce fichier dans Visual Studio, utilisez le bouton Show All Files dans l'Explorateur de solutions (Solution Explorer). Vous remarquerez qu'un fichier .wxs est maintenant visible. Double-cliquez dessus pour ouvrir le fichier.
Le contenu de ces fragments WiX complète l'histoire du paquet de l'installation. Deux fragments sont visibles. Le premier contient un élément DirectoryRef. Le but de cet élément est de permettre à plusieurs composants d'être placés dans le même répertoire sur la machine cible.
À l'intérieur de DirectoryRef se trouvent deux éléments Component. Chaque composante représente un fichier. La premier composante est l'exécutable du projet. La deuxième composante est le fichier de configuration. L'attribut Source indique les composantes.
Le deuxième fragment est le ComponentGroup discuté précédemment. La différence est que le ComponentGroup par rapport à la précédente est qu'il n'avait pas de fichiers. Celui-ci le fait. En particulier, les fichiers contenus dans ce ComponentGroup (tels que représentés par les éléments ComponentRef) font référence à l'identité des fichiers dans l'élément DirectoryRef. L'attribut Id dans ComponentRef correspond à l'Id dans Component dans DirectoryRef.
Cette indirection constante peut sembler exagéré. Et dans une certaine mesure, ça l'est. Mais cela permet une grande flexibilité. En définissant une référence de répertoire et en y incluant des composantes, vous pouvez placer des fichiers de différents composantes dans le même répertoire physique avec un minimum d'effort.
Les fragments générés par la chaleur doivent être incorporés dans le projet d'installation pour être inclus dans le paquet d'installation. Pour ce faire, copiez les deux fragments et collez-les dans le fichier Product.wxs à partir du projet d'installation. Ce faisant, supprimez le fragment ComponentGroup existant.
Maintenant, les deux composantes doivent être référencés dans le fichier Product.wxs. C'est fait en deux étapes. Tout d'abord, dans l'élément Feature du produit, définissez le ComponentGroupRef Id comme étant l'ID du ComponentGroup dans les fragments générés par Heat.
Deuxièmement, dans l'élément DirectoryRef du fragment généré par Heat, définissez l'ID sur INSTALLFOLDER. Cela lie les composantes (et les fichiers) dans le répertoire cible lorsque l'installation est effectuée.
L'installateur de services
Vous pouvez créer un programme d'installation pour un service Windows de la même manière que vous créeriez un programme d'installation pour une application Windows. Cependant, un programme d'installation de service Windows doit non seulement installer les fichiers à l'emplacement approprié, mais il doit également enregistrer le service afin qu'il apparaisse dans la liste des services.
Le WiX Toolset fournit un mécanisme pour ce faire. Ce sont les éléments ServiceInstall et ServiceControl décrivant ce que vous voulez qu'il se passe lorsque le service est installé.