Kompilera ett WPF-program
Windows Presentation Foundation-program (WPF) kan skapas som körbara .NET Framework-filer (.exe), bibliotek (.dll) eller en kombination av båda typerna av sammansättningar. Det här avsnittet beskriver hur du skapar WPF-program och beskriver de viktigaste stegen i byggprocessen.
Skapa ett WPF-program
Ett WPF-program kan kompileras på följande sätt:
Kommandorad. Programmet får endast innehålla kod (ingen XAML) och en programdefinitionsfil. För mer information, se Kompilering från kommandoraden med csc.exe eller Kompilering från kommandoraden (Visual Basic).
Microsoft Build Engine (MSBuild). Förutom koden och XAML-filerna måste programmet innehålla en MSBuild-projektfil. Mer information finns i "MSBuild".
Visual Studio. Visual Studio är en integrerad utvecklingsmiljö som kompilerar WPF-program med MSBuild och innehåller en visuell designer för att skapa användargränssnittet. Mer information finns i Skriva och hantera kod med Visual Studio och Design XAML i Visual Studio.
WPF-byggpipeline
När ett WPF-projekt skapas anropas kombinationen av språkspecifika och WPF-specifika mål. Processen att genomföra dessa mål kallas för bygg-pipeline, och de viktigaste stegen illustreras i följande bild.
Förbyggda initialiseringar
Innan du skapar bestämmer MSBuild platsen för viktiga verktyg och bibliotek, inklusive följande:
The .NET Framework.
Windows SDK-katalogerna.
Platsen för WPF-referenssammansättningar.
Egenskapen för sökvägar för assembly.
Den första platsen där MSBuild söker efter sammansättningar är referenssammansättningens katalog (%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.0\). Under det här steget initierar byggprocessen även de olika egenskaperna och objektgrupperna och utför alla nödvändiga rensningar.
Åtgärda referenser
Byggprocessen letar upp och binder de sammansättningar som krävs för att skapa programprojektet. Den här logiken finns i ResolveAssemblyReference
uppgift. Alla sammansättningar som deklareras som Reference
i projektfilen tillhandahålls till uppgiften tillsammans med information om sökvägar och metadata för sammansättningar som redan är installerade i systemet. Uppgiften söker efter sammansättningar och använder den installerade sammansättningens metadata för att filtrera bort de WPF-kärnsammansättningar som inte behöver visas i utdatamanifesten. Detta görs för att undvika redundant information i ClickOnce-manifesten. Eftersom PresentationFramework.dll till exempel kan betraktas som representativa för ett program som bygger på och för WPF, och eftersom alla WPF-sammansättningar finns på samma plats på varje dator som har .NET Framework installerat, behöver du inte inkludera all information om alla .NET Framework-referenssammansättningar i manifesten.
Markeringskompilering – Pass 1
I det här steget parsas och kompileras XAML-filer så att körningen inte ägnar tid åt att parsa XML och verifiera egenskapsvärden. Den kompilerade XAML-filen är förtokeniserad så att det vid körningen bör gå mycket snabbare att läsa in den än att läsa in en XAML-fil.
Under det här steget utförs följande aktiviteter för varje XAML-fil som är ett Page
byggobjekt:
XAML-filen parsas av markeringskompilatorn.
En kompilerad representation skapas för XAML och kopieras till mappen obj\Release.
En CodeDOM-representation av en ny partiell klass skapas och kopieras till mappen obj\Release.
Dessutom genereras en språkspecifik kodfil för varje XAML-fil. För en Page1.xaml-sida i ett Visual Basic-projekt genereras till exempel en Page1.g.vb. för en Sida1.xaml-sida i ett C#-projekt genereras en Page1.g.cs. ".g" i filnamnet anger att filen genereras kod som har en partiell klassdeklaration för elementet på den översta nivån i markeringsfilen (till exempel Page
eller Window
). Klassen deklareras med partial
-modifieraren i C# (Extends
i Visual Basic) för att indikera att det finns en annan deklaration för klassen någon annanstans, vanligtvis i filen bakom koden Page1.xaml.cs.
Den partiella klassen sträcker sig från lämplig basklass (till exempel Page för en sida) och implementerar System.Windows.Markup.IComponentConnector-gränssnittet. Det IComponentConnector gränssnittet har metoder för att initiera en komponent och ansluta namn och händelser på element i dess innehåll. Därför har den genererade kodfilen en metodimplementering som följande:
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
Som standard körs markeringskompilering i samma AppDomain som MSBuild-motorn. Detta ger betydande prestandavinster. Det här beteendet kan växlas med egenskapen AlwaysCompileMarkupFilesInSeparateDomain
. Detta har fördelen att ta bort alla referenssammansättningar genom att ta bort den separata AppDomain.
Markeringskompilering – pass 2
Alla XAML-sidor kompileras inte vid markeringskompileringens pass 1. XAML-filer som har lokalt definierade typreferenser (referenser till typer som definierats i kod någon annanstans i samma projekt) är undantagna från kompilering just nu. Det beror på att dessa lokalt definierade typer bara finns i källan och ännu inte har kompilerats. För att fastställa detta använder parsern heuristik som omfattar att söka efter objekt som x:Name
i markeringsfilen. När en sådan instans hittas skjuts markeringsfilens kompilering upp tills kodfilerna har kompilerats, varefter det andra kompileringspasset för markering bearbetar dessa filer.
Filklassificering
Byggprocessen placerar utdatafiler i olika resursgrupper baserat på vilken programsammansättning de ska placeras i. I ett typiskt icke-lokaliserat program placeras alla datafiler som markerats som Resource
i huvudsammansättningen (körbara eller bibliotek). När UICulture
anges i projektet placeras alla kompilerade XAML-filer och de resurser som är specifikt markerade som språkspecifika i satellitresurssammansättningen. Dessutom placeras alla språkneutrala resurser i huvudsammansättningen. I det här steget i byggprocessen görs den bestämningen.
De ApplicationDefinition
, Page
och Resource
byggåtgärderna i projektfilen kan utökas med Localizable
metadata (acceptabla värden är true
och false
), som avgör om filen är språkspecifik eller språkneutral.
Core-kompilering
Det grundläggande kompileringssteget omfattar kompilering av kodfiler. Detta samordnas av logik i de språkspecifika målfilerna Microsoft.CSharp.targets och Microsoft.VisualBasic.targets. Om heuristiken har fastställt att en enda passering av markeringskompilatorn är tillräcklig genereras huvudsammansättningen. Men om en eller flera XAML-filer i projektet har referenser till lokalt definierade typer genereras en tillfällig .dll fil så att de slutliga programsammansättningarna kan skapas när den andra markeringskompileringen har slutförts.
Manifestgenerering
När alla programsammansättningar och innehållsfiler är klara i slutet av byggprocessen genereras ClickOnce-manifesten för programmet.
Distributionsmanifestfilen beskriver distributionsmodellen: den aktuella versionen, uppdateringsbeteendet och utgivarens identitet tillsammans med digital signatur. Det här manifestet är avsett att skapas av administratörer som hanterar distributionen. Filtillägget är .xbap (för XAML-webbläsarprogram (XBAPs)) och .application för installerade program. Det förra styrs av HostInBrowser
projektegenskap och därför identifierar manifestet programmet som webbläsarhanterat.
Programmanifestet (en .exe.manifestfil) beskriver programsammansättningar och beroende bibliotek och listar behörigheter som krävs av programmet. Den här filen är avsedd att skapas av programutvecklaren. För att starta ett ClickOnce-program öppnar en användare programmets distributionsmanifestfil.
Dessa manifestfiler skapas alltid för XBAP:er. För installerade program skapas de inte om inte egenskapen GenerateManifests
anges i projektfilen med värdet true
.
XBAP:er får ytterligare två behörigheter utöver de behörigheter som tilldelats till vanliga Internetzonprogram: WebBrowserPermission och MediaPermission. WPF-byggsystemet deklarerar dessa behörigheter i programmanifestet.
Inkrementellt byggstöd
WPF-byggsystemet ger stöd för inkrementella versioner. Det är ganska intelligent när det gäller att identifiera ändringar som gjorts i markering eller kod, och det kompilerar endast de artefakter som påverkas av ändringen. Den inkrementella byggmekanismen använder följande filer:
En $(AssemblyName)_MarkupCompiler.Cache-fil för att upprätthålla aktuellt kompilatortillstånd.
En $(AssemblyName-)_MarkupCompiler.lref-fil som cachelagrar XAML-filerna med referenser till lokalt definierade typer.
Följande är en uppsättning regler som styr inkrementell bygge:
Filen är den minsta enhet där byggsystemet identifierar ändringar. För en kodfil kan byggsystemet alltså inte avgöra om en typ har ändrats eller om koden har lagts till. Samma gäller för projektfiler.
Den inkrementella byggmekanismen måste vara medveten om att en XAML-sida antingen definierar en klass eller använder andra klasser.
Om
Reference
-poster ändras, kompilera då om alla sidor.Om en kodfil ändras, kompilera om alla sidor med lokalt definierade typreferenser.
Om en XAML-fil ändras:
Om XAML deklareras som
Page
i projektet: om XAML inte har lokalt definierade typreferenser, kompilera om XAML plus alla XAML-sidor med lokala referenser. Om XAML har lokala referenser kan du kompilera om alla XAML-sidor med lokala referenser.Om XAML deklareras som
ApplicationDefinition
i projektet: kompilera om alla XAML-sidor (orsak: varje XAML har en referens till en Application typ som kan ha ändrats).
Om projektfilen deklarerar en kodfil som programdefinition i stället för en XAML-fil:
Kontrollera om
ApplicationClassName
värdet i projektfilen har ändrats (finns det en ny programtyp?). I så fall kan du kompilera om hela programmet.Annars kan du kompilera om alla XAML-sidor med lokala referenser.
Om en projektfil ändras: tillämpa alla föregående regler och se vad som behöver kompileras om. Ändringar i följande egenskaper utlöser en fullständig omkompilering:
AssemblyName
,IntermediateOutputPath
,RootNamespace
ochHostInBrowser
.
Följande omkompileringsscenarier är möjliga:
Hela programmet kompileras om.
Endast de XAML-filer som har lokalt definierade typreferenser kompileras om.
Ingenting är omkompilerat (om inget i projektet har ändrats).
Se även
.NET Desktop feedback