Sdílet prostřednictvím


Kompilace aplikace WPF

Aplikace WINDOWS Presentation Foundation (WPF) lze sestavit jako spustitelné soubory rozhraní .NET Framework (.exe), knihovny (.dll) nebo kombinaci obou typů sestavení. Toto téma představuje, jak sestavovat aplikace WPF a popisuje klíčové kroky v procesu sestavení.

Vytvoření aplikace WPF

Aplikaci WPF lze zkompilovat následujícími způsoby:

Sestavovací proces WPF

Při sestavení projektu WPF se vyvolá kombinace cílů specifických pro jazyk a WPF. Proces provádění těchto cílů se nazývá kanál buildu a klíčové kroky jsou znázorněny na následujícím obrázku.

procesu sestavení WPF

Inicializace před sestavením

Před sestavením nástroj MSBuild určuje umístění důležitých nástrojů a knihoven, včetně následujících:

  • The .NET Framework.

  • Adresáře sady Windows SDK.

  • Umístění referenčních sestavení WPF.

  • Vlastnost pro cesty pro vyhledávání sestavení.

Prvním umístěním, kde nástroj MSBuild hledá sestavení, je referenční adresář sestavení (%ProgramFiles%\Referenční sestavení\Microsoft\Framework\v3.0\). Během tohoto kroku proces sestavení také inicializuje různé vlastnosti a skupiny položek a provede všechny požadované vyčištění.

Řešení odkazů

Proces sestavení vyhledá a naváže sestavení potřebná k sestavení projektu aplikace. Tato logika je obsažena v úloze ResolveAssemblyReference. Všechna sestavení deklarovaná jako Reference v souboru projektu jsou poskytnuta úloze spolu s informacemi o vyhledávacích cestách a metadatech sestavení, která jsou již v systému nainstalována. Úloha vyhledá sestavení a použije metadata nainstalovaného sestavení k vyfiltrování základních sestavení WPF, která se nemusí zobrazit ve výstupních manifestech. Tím se zabrání nadbytečným informacím v manifestech ClickOnce. Například vzhledem k tomu, že PresentationFramework.dll lze považovat za zástupce aplikace založené na WPF a pro WPF a vzhledem k tomu, že všechna sestavení WPF existují ve stejném umístění na každém počítači s nainstalovaným rozhraním .NET Framework, není nutné do manifestů zahrnout všechny informace o všech referenčních sestaveních rozhraní .NET Framework.

Kompilace značek – Pass 1

V tomto kroku jsou soubory XAML analyzovány a kompilovány, takže runtime nedochází k trávení času analýzou XML a ověřováním hodnot vlastností. Zkompilovaný soubor XAML je předem tokenizován tak, aby při načítání souboru XAML v době běhu mělo být mnohem rychlejší než načtení souboru XAML.

V tomto kroku probíhají následující aktivity pro každý soubor XAML, který je Page položkou sestavení:

  1. Soubor XAML je analyzován kompilátorem značek.

  2. Vytvoří se zkompilovaná reprezentace pro tento XAML a zkopíruje se do složky obj\Release.

  3. Vytvoří se reprezentace nové částečné třídy CodeDOM a zkopíruje se do složky obj\Release.

Kromě toho se pro každý soubor XAML vygeneruje soubor kódu specifický pro jazyk. Například pro stránku Page1.xaml v projektu jazyka Visual Basic se vygeneruje Page1.g.vb; pro stránku Page1.xaml v projektu C# se vygeneruje Page1.g.cs. Znak ".g" v názvu souboru označuje, že se jedná o generovaný kód, který má částečnou deklaraci třídy pro prvek nejvyšší úrovně souboru značkování (například Page nebo Window). Třída je deklarována pomocí modifikátoru partial v jazyce C# (Extends v jazyce Visual Basic), která indikuje, že existuje další deklarace pro třídu jinde, obvykle v souboru kódu za Page1.xaml.cs.

Částečná třída se rozšiřuje z příslušné základní třídy (například Page pro stránku) a implementuje System.Windows.Markup.IComponentConnector rozhraní. Rozhraní IComponentConnector má metody inicializace komponenty a propojení názvů a událostí prvků v obsahu. V důsledku toho má vygenerovaný soubor kódu implementaci metody, jako je následující:

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

Ve výchozím nastavení se kompilace značek spouští ve stejném AppDomain jako modul MSBuild. To poskytuje významné zvýšení výkonu. Toto chování lze přepnout pomocí vlastnosti AlwaysCompileMarkupFilesInSeparateDomain. To má tu výhodu, že odstranění všech referenčních sestavení se dosáhne tím, že se odstraní oddělený proces AppDomain.

Kompilace značkovacího jazyka – Fáze 2

Ne všechny stránky XAML jsou zkompilovány během prvního průchodu kompilace značek. Soubory XAML, které mají místně definované odkazy na typy (odkazy na typy definované v kódu jinde ve stejném projektu), jsou v tuto chvíli vyloučeny z kompilace. Důvodem je to, že tyto místně definované typy existují pouze ve zdroji a ještě nebyly zkompilovány. Aby to bylo možné zjistit, analyzátor používá heuristiku, která zahrnuje hledání položek, jako je x:Name v souboru značek. Pokud je taková instance nalezena, kompilace souboru revizí je odložena, dokud se soubory kódu nezkompilují, poté druhá kompilace revizí tyto soubory zpracuje.

Klasifikace souborů

Proces sestavení umístí výstupní soubory do různých skupin prostředků na základě toho, do kterého sestavení aplikace se umístí. V typické nelokalizované aplikaci jsou všechny datové soubory označené jako Resource umístěny v hlavním sestavení (spustitelný soubor nebo knihovna). Při nastavení UICulture v projektu se všechny kompilované soubory XAML a tyto prostředky, které jsou speciálně označené jako specifické pro jazyk, umístí do sestavení satelitních zdrojů. Kromě toho se všechny jazykově neutrální prostředky umístí do hlavního sestavení. V tomto kroku procesu sestavení se provádí toto rozhodnutí.

Akce sestavení ApplicationDefinition, Pagea Resource v souboru projektu je možné rozšířit o metadata Localizable (přijatelné hodnoty jsou true a false), což určuje, jestli je soubor jazykově nebo jazykově neutrální.

Kompilace jádra

Základní krok kompilace zahrnuje kompilaci souborů kódu. Tato funkce je orchestrována logikou v souborech cíle specifických pro jazyk Microsoft.CSharp.targets a Microsoft.VisualBasic.targets. Pokud heuristiky zjistily, že stačí jeden průchod kompilátoru značek, vygeneruje se hlavní sestavení. Pokud ale jeden nebo více souborů XAML v projektu obsahuje odkazy na místně definované typy, vygeneruje se dočasný soubor .dll, aby se po dokončení druhé kompilace značek mohla vytvořit konečná sestavení aplikace.

Generování manifestu

Po dokončení procesu sestavení se po dokončení všech sestavení aplikace a souborů obsahu vygenerují manifesty ClickOnce pro aplikaci.

Soubor manifestu nasazení popisuje model nasazení: aktuální verzi, chování aktualizace a identitu vydavatele spolu s digitálním podpisem. Tento manifest má vytvářet správci, kteří zpracovávají nasazení. Přípona souboru je .xbap (pro aplikace prohlížeče XAML (XBAPs)) a .application pro nainstalované aplikace. První vlastnost je diktována vlastností projektu HostInBrowser a v důsledku toho manifest identifikuje aplikaci jako hostovanou v prohlížeči.

Manifest aplikace (soubor .exe.manifest) popisuje sestavení aplikace a závislé knihovny a uvádí oprávnění vyžadovaná aplikací. Tento soubor má vytvořit vývojář aplikace. Aby bylo možné spustit aplikaci ClickOnce, uživatel otevře soubor manifestu nasazení aplikace.

Tyto soubory manifestu se vždy vytvářejí pro XBAPs. Nejsou vytvořeny pro nainstalované aplikace, pokud není v souboru projektu zadána vlastnost GenerateManifests s hodnotou true.

XBAPs získají dvě další oprávnění nad těmito oprávněními přiřazenými typickým aplikacím internetové zóny: WebBrowserPermission a MediaPermission. Systém sestavení WPF deklaruje tato oprávnění v manifestu aplikace.

Podpora přírůstkového sestavení

Systém sestavení WPF poskytuje podporu přírůstkových sestavení. Je poměrně inteligentní pro detekci změn provedených ve značkách nebo kódu a zkompiluje pouze ty artefakty ovlivněné změnou. Mechanismus přírůstkového sestavení používá následující soubory:

  • Soubor $(AssemblyName)_MarkupCompiler.Cache pro zachování aktuálního stavu kompilátoru.

  • Soubor $(AssemblyName)_MarkupCompiler.lref pro ukládání souborů XAML do mezipaměti s odkazy na místně definované typy.

Následuje sada pravidel pro inkrementální sestavení:

  • Soubor je nejmenší jednotka, ve které systém sestavení detekuje změnu. V případě souboru kódu tedy systém sestavení nemůže zjistit, jestli byl typ změněn nebo jestli byl přidán kód. Totéž platí pro soubory projektu.

  • Mechanismus přírůstkového sestavení musí být obeznámen s tím, že stránka XAML buď definuje třídu, nebo používá jiné třídy.

  • Pokud se Reference položky změní, překompilujte všechny stránky.

  • Pokud se soubor kódu změní, překompilujte všechny stránky s místně definovanými odkazy na typ.

  • Pokud se soubor XAML změní:

    • Pokud je XAML deklarován jako Page v projektu: pokud XAML nemá místně definované odkazy na typy, překompilujte xaml a všechny stránky XAML s místními odkazy; pokud xaml obsahuje místní odkazy, překompilujte všechny stránky XAML s místními odkazy.

    • Pokud je XAML deklarován jako ApplicationDefinition v projektu: překompilujte všechny stránky XAML (důvod: každý XAML má odkaz na Application typ, který se mohl změnit).

  • Pokud soubor projektu deklaruje soubor kódu jako definici aplikace místo souboru XAML:

    • Zkontrolujte, jestli se změnila hodnota ApplicationClassName v souboru projektu (existuje nový typ aplikace?). Pokud ano, překompilujte celou aplikaci.

    • V opačném případě překompilujte všechny stránky XAML s místními odkazy.

  • Pokud se soubor projektu změní: použijte všechna předchozí pravidla a zjistěte, co je potřeba překompilovat. Změny následujících vlastností aktivují úplné překompilování: AssemblyName, IntermediateOutputPath, RootNamespacea HostInBrowser.

Možné jsou následující scénáře rekompilu:

  • Celá aplikace je rekompilována.

  • Rekompilují se pouze soubory XAML, které mají místně definované odkazy na typy.

  • Nic se nekompiluje (pokud se nic v projektu nezměnilo).

Viz také