Génération d'une application WPF (WPF)

Les applications Windows Presentation Foundation (WPF) peuvent être générées comme fichiers exécutables .NET Framework (.exe), comme bibliothèques (.dll) ou une combinaison des deux types d'assemblys. Cette rubrique présente comment générer des applications WPF et décrit les principales étapes du processus de génération.

Cette rubrique comprend les sections suivantes.

  • Génération d'une application WPF
  • Pipeline de génération WPF
  • Support de génération incrémentiel
  • Rubriques connexes

Génération d'une application WPF

Une application WPF peut être compilée des façons suivantes :

Pipeline de génération WPF

Lorsqu'un projet WPF est généré, la combinaison de cibles spécifiques à une langue et spécifiques à WPF est appelée. Le processus d'exécution de ces cibles est appelé le pipeline de génération, et les étapes clés sont représentées par l'illustration suivante.

Processus de génération WPF

Initialisations avant génération

Avant la génération, MSBuild détermine l'emplacement des outils et des bibliothèques importants, y compris les éléments suivants :

  • .NET Framework.

  • Les répertoires Windows SDK.

  • L'emplacement d'assemblys de référence WPF.

  • La propriété pour les chemins de recherche des assemblys.

Le premier emplacement où MSBuild recherche les assemblys est le répertoire de l'assembly de référence (%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.0\). Pendant cette étape, le processus de génération initialise également les diverses propriétés et groupes d'éléments et exécute tout travail de nettoyage requis.

Résolution de références

Le processus de génération localise et lie les assemblys requis pour générer le projet d'application. Cette logique est contenue dans la tâche ResolveAssemblyReference. Tous les assemblys déclarés comme Reference dans le fichier projet sont fournis à la tâche avec les informations sur les chemins de recherche et les métadonnées sur les assemblys déjà installés sur le système. La tâche examine les assemblys et utilise les métadonnées de l'assembly installé pour éliminer par filtrage les assemblys WPF principaux qui ne doivent pas apparaître dans les manifestes de sortie. Cela est fait pour éviter des informations redondantes dans les manifestes ClickOnce. Par exemple, comme PresentationFramework.dll peut être considéré être représentatif d'une application générée sur et pour le WPF et, qui plus est, comme tous les assemblys WPF existent au même emplacement sur chaque ordinateur où .NET Framework est installé, il n'est pas besoin d'inclure toutes les informations sur tous les assemblys .NET Framework de référence dans les manifestes.

Compilation de la balise—Passe 1

Dans cette étape, les fichiers XAML sont analysés et compilés afin que le runtime ne perde pas de temps à analyser XML et à valider des valeurs de propriété. Le fichier XAML compilé est sous forme de pré-jetons de sorte que, lors de l'exécution, le chargement devrait être beaucoup plus rapide que le chargement d'un fichier XAML.

Pendant cette étape, les activités suivantes ont lieu pour chaque fichier XAML qui est un élément de génération Page :

  1. Le fichier XAML est analysé par le compilateur de balise.

  2. Une représentation compilée est créée pour ce XAML et copiée dans le dossier obj\Release.

  3. Une représentation CodeDOM d'une nouvelle classe partielle est créée et copiée dans le dossier obj\Release.

En outre, un fichier de code spécifique à un langage est généré pour chaque fichier XAML. Par exemple, pour une page Page1.xaml dans un projet Visual Basic, un fichier Page1.g.vb est généré ; pour une page Page1.xaml dans un projet C#, un fichier Page1.g.cs est généré. Le ".g" dans le nom de fichier indique que le fichier est du code généré qui a une déclaration de classe partielle pour l'élément de niveau supérieur du fichier de balisage (tel que Page ou Window). La classe est déclarée avec le modificateur partial dans C# (Extends dans Visual Basic) pour indiquer qu'une autre déclaration existe ailleurs pour la classe, habituellement dans le fichier code-behind Page1.xaml.cs.

La classe partielle s'étend de la classe de base appropriée (telle que Page pour une page) et implémente l'interface System.Windows.Markup.IComponentConnector. L'interface IComponentConnector a des méthodes pour initialiser un composant et connecter des noms et des événements sur les éléments dans son contenu. Par conséquent, le fichier de code généré a une implémentation de méthode comme suit :

public void InitializeComponent() {
    if (_contentLoaded) {
        return;
    }
    _contentLoaded = true;
    System.Uri resourceLocater = 
        new System.Uri(
            "window1.xaml", 
            System.UriKind.RelativeOrAbsolute);
    System.Windows.Application.LoadComponent(this, resourceLocater);
}
Public Sub InitializeComponent() _

    If _contentLoaded Then
        Return
    End If

    _contentLoaded = True
    Dim resourceLocater As System.Uri = _
        New System.Uri("mainwindow.xaml", System.UriKind.Relative)

    System.Windows.Application.LoadComponent(Me, resourceLocater)

End Sub

Par défaut, la compilation de balise s'exécute dans le même AppDomain que le moteur MSBuild. Cela assure des gains de performance significatifs. Ce comportement peut être basculé avec la propriété AlwaysCompileMarkupFilesInSeparateDomain. Cela présente l'avantage de décharger tous les assemblys de référence en déchargeant le AppDomain séparé.

Compilation de la balise—Passe 2

Toutes les pages XAML ne sont pas compilées pendant la première passe de la compilation de balisage. Les fichiers XAML qui ont des références de type définies localement (références à des types définis ailleurs dans le code d'un même projet) sont exemptés de compilation à ce moment. Ceci parce que les types localement définis existent uniquement dans la source et n'ont pas encore été compilés. Pour déterminer ceci, l'analyseur utilise des heuristiques qui impliquent la recherche d'éléments tels que x:Name dans le fichier de balisage. Lorsqu'une telle instance est trouvée, la compilation de ce fichier de balisage est remise à plus tard jusqu'à ce que les fichiers de code aient été compilés, après quoi la deuxième passe de la compilation de la balise traite ces fichiers.

Classification des fichiers

Le processus de génération organise les fichiers de sortie dans différents groupes de ressources en fonction de l'assembly d'application dans lequel ils seront placés. Dans une application non localisée type, tous les fichiers de données marqués comme Resource sont placés dans l'assembly principal (fichier exécutable ou bibliothèque). Lorsque UICulture est défini dans le projet, tous les fichiers XAML compilés et les ressources marquées spécifiquement comme spécifiques à une langue sont placés dans l'assembly de ressource satellite. En outre, toutes les ressources indépendantes du langage sont placées dans l'assembly principal. Cette détermination est faite lors de cette étape du processus de génération.

Les ApplicationDefinition, Page et les actions de génération Resource dans le fichier projet peuvent être augmentés avec les métadonnées Localizable (les valeurs acceptables sont true et false), qui déterminent si le fichier est spécifique ou indépendant du langage.

Compilation principale

L'étape de compilation principale implique la compilation de fichiers de code. Cela répond à une logique dans les fichiers cibles Microsoft.CSharp.targets et Microsoft.VisualBasic.targets spécifiques à une langue. Si les heuristiques ont déterminé qu'un seul passage du compilateur de balisage suffit, l'assembly principal est alors généré. Toutefois, si un ou plusieurs fichiers XAML dans le projet ont des références à des types définis localement, un fichier .dll temporaire est alors généré afin que les derniers assemblys d'application puissent être créés après la fin de la deuxième passe de compilation de balise.

Génération de manifeste

À la fin du processus de génération, après que tous les assemblys d'application et les fichiers de contenu sont prêts, les manifestes ClickOnce pour l'application sont générés.

Le fichier manifeste de déploiement décrit le modèle de déploiement : la version actuelle, le comportement de mise à jour et l'identité d'éditeur avec la signature numérique. Ce manifeste est prévu pour être créé par les administrateurs qui gèrent le déploiement. L'extension de fichier est .xbap (pour les XAML browser applications (XBAPs)) et .application pour les applications installées. La première extension est déterminée par la propriété du projet HostInBrowser et, en conséquence, le manifeste identifie l'application comme étant hébergée par le navigateur.

Le manifeste de l'application (un fichier .exe.manifest) décrit les assemblys d'application et les bibliothèques dépendantes et répertorie les autorisations requises par l'application. Ce fichier est prévu pour être créé par le développeur d'applications. Pour lancer une application ClickOnce, un utilisateur ouvre le fichier manifeste de déploiement de l'application.

Ces fichiers manifeste sont toujours créés pour XBAPs. Pour les applications installées, ils ne sont pas créés à moins que la propriété GenerateManifests ne soit spécifiée dans le fichier projet avec la valeur true.

Les applications XBAPs obtiennent deux autorisations supplémentaires en plus de celles assignées aux applications de zone Internet typiques : WebBrowserPermission et MediaPermission. Le système de génération WPF déclare ces autorisations dans le manifeste de l'application.

Support de génération incrémentiel

Le système de génération WPF fournit le support pour les générations incrémentielles. Il est assez intelligent pour détecter les modifications apportées à la balise ou au code, et il compile uniquement les artefacts affectés par la modification. Le mécanisme de génération incrémentiel utilise les fichiers suivants :

  • Un fichier $ (NomAssembly)_MarkupCompiler.Cache pour gérer l'état du compilateur actuel.

  • Un fichier $ (NomAssembly)_MarkupCompiler.lref pour mettre en cache les fichiers XAML avec les références aux types définis localement.

Les éléments suivants sont un jeu des règles gouvernant la génération incrémentielle :

  • Le fichier est la plus petite unité au niveau de laquelle le système de génération détecte une modification. Ainsi, pour un fichier de code, le système de génération ne peut pas déterminer si un type a été modifié ou si du code a été ajouté. Le même raisonnement s'applique aux fichiers projet.

  • Le mécanisme de génération incrémentiel doit être informé qu'une page XAML définit une classe ou utilise d'autres classes.

  • Si des entrées Reference sont modifiées, vous devez recompiler toutes les pages.

  • Si un fichier de code est modifié, recompiler toutes les pages avec des références définies localement.

  • Si un fichier XAML est modifié :

    • Si XAML est déclaré comme Page dans le projet : si le XAML ne contient pas de références de type définies localement, recompiler ce XAML plus toutes les pages XAML avec des références locales ; si le XAML contient des références locales, recompiler toutes les pages XAML avec les références locales.

    • Si XAML est déclaré comme ApplicationDefinition dans le projet : recompiler toutes les pages XAML (raison : chaque XAML fait référence à un type Application qui a pu changer).

  • Si le fichier projet déclare un fichier de code comme définition d'application au lieu d'un fichier XAML :

    • Vérifiez si la valeur ApplicationClassName dans le fichier projet a changé (y a-t-il un nouveau type d'application ?). Si c'est le cas, recompiler toute l'application.

    • Sinon, recompiler toutes les pages XAML avec des références locales.

  • Si un fichier projet change : appliquer toutes les règles précédentes et voir ce qui doit être recompilé. Les modifications apportées aux propriétés suivantes entraînent une recompilation complète : AssemblyName, IntermediateOutputPath, RootNamespace et HostInBrowser.

Les scénarios de recompilation suivants sont possibles :

  • Toute l'application est recompilée.

  • Seuls les fichiers XAML qui contiennent des références de type définies localement sont recompilés.

  • Rien n'est recompilé (si rien dans le projet n'a changé).

Voir aussi

Concepts

Déploiement d'une application WPF (WPF)

URI à en-tête pack dans WPF

Fichiers de ressources, de contenu et de données d'une application WPF

Autres ressources

Référence MSBuild - WPF

Historique des modifications

Date

Historique

Motif

Novembre 2010

Ajout de l'exemple Visual Basic manquant.

Résolution des bogues de contenu.