Building a WPF Application (WPF)

Windows Presentation Foundation (WPF) applications can be built as .NET Framework executables (.exe), libraries (.dll), or a combination of both types of assemblies. This topic initially shows how to build simple WPF applications from the command prompt, before showing how WPF leverages the extensibility of Microsoft build engine (MSBuild) to build more complex applications. This topic finishes by providing an in-depth discussion of the key steps in the MSBuild build process.

This topic contains the following sections.

  • Building a WPF Application by Using Command-Line Compilation
  • Building a WPF Application by Using MSBuild
  • MSBuild Project Files for WPF
  • Creating an MSBuild Project for WPF by Using Visual Studio
  • Building an MSBuild Project for WPF
  • Windows Presentation Foundation Build Pipeline
  • Incremental Build Support
  • Related Topics

Building a WPF Application by Using Command-Line Compilation

A WPF application written entirely in code (no markup) can be built with a command-line compiler. For example, consider a C# WPF standalone application that includes the following source code files:

  • An application definition file (app.cs).

  • A window (mainwindow.cs).

This application can be built using the C# compiler, csc.exe, from a command prompt, as in the following example:

csc.exe
  /out:WPFApplication.exe
  /target:winexe 
  app.cs mainwindow.cs 
  /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\presentationframework.dll" 
  /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\windowsbase.dll" 
  /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\presentationcore.dll"

In this example:

  • The /out parameter specifies the name of the built executable assembly (WPFApplication.exe).

  • The /target parameter specifies type of assembly that is compiled (a Microsoft Windows executable).

  • The C# source code files that make up the application (app.cs and mainwindow.cs)

  • The /reference parameter that identifies the referenced assemblies that implement the types used by the application.

Command-line compilation can be used to build applications with more complexity, although the compiler does not support WPF applications that include Extensible Application Markup Language (XAML) source code. Furthermore, command-line compilation does not support the full range of build requirements of typical WPF applications, including configuration management and ClickOnce manifest generation. To support these and other more complex build requirements, WPF integrates with and extends MSBuild.

Note

For more information on command-line compilation, see Command-line Building With csc.exe or Building from the Command Line (Visual Basic).

Building a WPF Application by Using MSBuild

MSBuild is a robust, extensible technology that was introduced with the .NET Framework. The core of the MSBuild technology is implemented across the assemblies that are described in the following table.

Assembly

Description

Microsoft.Build.Engine.dll

Reads and processes MSBuild project files.

Microsoft.Build.Tasks.dll

Implements functionality that is common to all MSBuild projects, including command-line compiler invocation (for example, csc.exe for C#, vbc.exe for Visual Basic).

Microsoft.Build.Utilities.dll

Exposes utility classes that extend MSBuild with custom build functionality.

Microsoft.Build.Framework.dll

Implements interfaces that define how MSBuild functionality interacts with the MSBuild engine.

Microsoft.Build.Conversion.dll

Supports conversion from legacy Microsoft Visual Studio .NET 2002 and Microsoft Visual Studio .NET 2003 project file format to Microsoft Visual Studio 2005 MSBuild project file format.

Note

For more information on the MSBuild assemblies, see MSBuild Reference.

MSBuild Project Files for WPF

The assemblies that make up MSBuild are referred to as the MSBuild engine. To build applications, the MSBuild engine typically requires the following information:

  • Source code file references.

  • Dependent assembly references.

  • Configuration details.

  • Build requirements.

To be processed by MSBuild, this information is packaged in XML files that conform to the custom MSBuild schema (see MSBuild Project File Schema Reference). Such files are known as MSBuild project files. The following is the MSBuild project file for a version of the WPF application we built earlier using a command-line compiler, with the addition of Extensible Application Markup Language (XAML) source code files.

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
     <PropertyGroup>
         <AssemblyName>WPFApplication</AssemblyName>
         <OutputType>winexe</OutputType>
     </PropertyGroup>
     <ItemGroup>
         <Reference Include="System" />
         <Reference Include="WindowsBase" />
         <Reference Include="PresentationCore" />
         <Reference Include="PresentationFramework" />
     </ItemGroup>
     <ItemGroup>
         <ApplicationDefinition Include="App.xaml" />
         <Compile Include="App.xaml.cs" />
         <Page Include="MainWindow.xaml" />
         <Compile Include="MainWindow.xaml.cs" />
     </ItemGroup>
     <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
     <Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" />
</Project>

This example contains the elements that are common to most MSBuild project files, including the Project tag, properties, items, targets, and tasks.

The Project Element

As specified by the MSBuild project file schema, an MSBuild project file is an XML file with Project as the top-level element:

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
     ...
</Project>

The Project element is where the MSBuild engine starts processing a project file. To specify the version of MSBuild that the MSBuild project file targets, an appropriate XML namespace declaration is provided.

Properties

Properties are variables that are used to both configure MSBuild projects and provide build-specific information to the MSBuild engine. Properties are contained within PropertyGroup elements, as shown in the following example.

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
     <PropertyGroup>
         <AssemblyName>WPFApplication</AssemblyName>
         <OutputType>winexe</OutputType>
     </PropertyGroup>
     ...
</Project>

Some properties, such as AssemblyName and OutputType, are common to all application types and are described in Common MSBuild Project Properties. The MSBuild properties that are specific to WPF are listed in the following table.

Property

Description

OutputType

Specifies the type of assembly that is built, and is one of the following values:

  • winexe: Builds an executable assembly (.exe). Standalone applications and XBAPs are configured with this output type.

  • library: Builds a library assembly (.dll). Shared assemblies and custom control libraries are configured with this output type.

HostInBrowser

Specifies whether a WPF application is hosted in a browser, and is one of the following values:

  • true: Creates an XBAP, which includes the main application assembly (.exe), a deployment manifest (applicationName.xbap), and an application manifest (applicationName.exe.manifest).

  • false: Creates a standalone application.

If HostInBrowser is true, the OutputType must be winexe.

Install

Specifies whether an XBAP is installed on the client. Install can be either true or false, and has the opposite value of HostInBrowser.

GenerateManifests

Specifies whether a standalone application is published using ClickOnce deployment, and is one of the following values:

  • true: Creates the main application executable, a deployment manifest (applicationName.application), and an application manifest (applicationName.exe.manifest).

  • false: Creates just the application executable (.exe).

GenerateManifests is used only when Install has a value of true.

UICulture

Specifies the locale for which the assembly will be built. When specified, files declared as Resource project items and language-specific resources are compiled into a satellite assembly for the desired locale. Language-neutral content, on the other hand, is compiled into the main assembly. By default, applications are not localized, and resource files are consequently embedded in the main assembly.

Note

When UICulture is set, the neutral resource language must be specified using the NeutralResourcesLanguageAttribute. This attribute must be added to a WPF application's AssemblyInfo file.

Items

Items are MSBuild inputs that are processed by the MSBuild engine during the build process. Items are contained within an ItemGroup element.

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
     ...
     <ItemGroup>
         <Reference Include="System" />
         <Reference Include="WindowsBase" />
         <Reference Include="PresentationCore" />
         <Reference Include="PresentationFramework" />
     </ItemGroup>
     <ItemGroup>
         <ApplicationDefinition Include="App.xaml" />
         <Compile Include="App.xaml.cs" />
         <Page Include="MainWindow.xaml" />
         <Compile Include="MainWindow.xaml.cs" />
     </ItemGroup>
     ...
</Project>

An item's type can be configured with metadata; in the preceding example, assembly references are configured as Reference items, and source code files are configured as Compile items. Reference and Compile items are common to all .NET Framework applications and are described further in Common MSBuild Project Items.

The WPF-specific MSBuild items are listed in the following table.

Property

Description

ApplicationDefinition

Identifies the XAML markup file that contains the application definition (a XAML markup file whose root element is Application). ApplicationDefinition is mandatory when Install is true and OutputType is winexe. A WPF application and, consequently, an MSBuild project can only have one ApplicationDefinition.

Page

Identifies a XAML markup file whose content is converted to a binary format and compiled into an assembly. Page items are typically implemented in conjunction with a code-behind class.

The most common Page items are XAML files whose top-level elements are one of the following:

Resource

Identifies a resource file that is compiled into an application assembly. As mentioned earlier, UICulture processes Resource items.

Content

Identifies a content file that is distributed with an application. Metadata that describes the content file is compiled into the application (using AssemblyAssociatedContentFileAttribute).

SplashScreen

Identifies an image file that is used for the application's startup window. The PresentationBuildTasks assembly generates code into App.g.cs or Application.g.vb that creates a SplashScreen instance and displays it while the application is loading. This item is available starting in Visual Studio 2008 SP1.

Targets

Targets determine how projects are built and depend on both properties and items. A WPF application must have a language-specific target and a WPF-specific target.

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
     ...
     <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
     <Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" />
</Project>

Targets are separate files that end with the .targets extension. The target files that are included with .NET Framework are installed in the following location:

%WINDIR%\Microsoft.NET\Framework\vX.X.X

The language-specific target builds language-specific source code. The language-specific target for C# is Microsoft.CSharp.targets and Microsoft.VisualBasic.targets for Visual Basic. Both of these targets derive from and extend the Microsoft.Common.targets target, which performs the bulk of the common, language-independent build work. For more information on common and language-specific MSBuild targets, see MSBuild .Targets Files.

WPF-specific build work is performed by the Microsoft.WinFX.targets target. This work includes XAML markup compilation, manifest generation for XBAP applications, and processing WPF resource and content files.

Tasks

A task is a class that performs a specific build action. One or more tasks are combined by targets to define a build process; when MSBuild processes a target, it executes the tasks that are contained by the target. The tasks that are used by common and language-specific targets are implemented by the Microsoft.Build.Tasks assembly, and the tasks that are specific to WPF are implemented by the PresentationBuildTasks assembly.

Targets provide the support to build all standard WPF applications. It is also possible to use alternative combinations of tasks to implement custom build behavior. For example, the following MSBuild GetWinFXPath task is used to detect the native path to the .NET Framework runtime, which is dependent on whether the task is executing on a 64 bit processor:

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
     <UsingTask 
         TaskName="Microsoft.Build.Tasks.Windows.GetWinFXPath" 
         AssemblyFile="C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationBuildTasks.dll" />
     <Target Name="GetWinFXPathTask">
         <GetWinFXPath
             WinFXNativePath="c:\DOTNet3Native" 
             WinFXWowPath="c:\DOTNet3WowNative" />
     </Target>
     <Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" />
</Project>

For more information on the common MSBuild tasks, see MSBuild Task Reference.

Windows Presentation Foundation MSBuild Project Samples

The Windows Software Development Kit (SDK) includes several example MSBuild project files for the most common types of WPF applications:

Creating an MSBuild Project for WPF by Using Visual Studio

Visual Studio automatically generates MSBuild project files when new WPF applications are created using the Visual Studio project templates. For example, the WPF Application project template generates the following project file (for C#):

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.20726</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{E0EA3EBA-718C-4122-B20C-EB97B7DC6604}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>WpfApplication1</RootNamespace>
    <AssemblyName>WpfApplication1</AssemblyName>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <ProjectTypeGuids>
      {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};
      {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
    </ProjectTypeGuids>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Xml.Linq">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Data.DataSetExtensions">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
    <Reference Include="WindowsBase" />
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />
  </ItemGroup>
  <ItemGroup>
    <ApplicationDefinition Include="App.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </ApplicationDefinition>
    <Page Include="Window1.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </Page>
    <Compile Include="App.xaml.cs">
      <DependentUpon>App.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="Window1.xaml.cs">
      <DependentUpon>Window1.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Properties\AssemblyInfo.cs">
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="Properties\Settings.Designer.cs">
      <AutoGen>True</AutoGen>
      <DependentUpon>Settings.settings</DependentUpon>
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
    </Compile>
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
      <SubType>Designer</SubType>
    </EmbeddedResource>
    <None Include="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
    </None>
    <AppDesigner Include="Properties\" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>

The name of the generated MSBuild project file extension incorporates the source code language:

  • For C# projects, the extension is .csproj.

  • For Visual Basic projects, the extension is **.**vbproj.

The project file is larger than the previous examples, which is partly due to several additional properties. However, the additional information is Visual Studio-specific and includes the following:

  • Project configuration.

  • Build configuration.

  • Source code file association.

  • Default project property, resource, and settings management.

Project Configuration

The project configuration details include a unique identifier for the project, a unique identifier for the project type, and various data identifying the .NET Framework and Visual Studio version:

<Project 
  ToolsVersion="3.5"
  DefaultTargets="Build"
  xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <ProductVersion>9.0.20726</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{E0EA3EBA-718C-4122-B20C-EB97B7DC6604}</ProjectGuid>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <ProjectTypeGuids>
      {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};
      {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
    </ProjectTypeGuids>
  </PropertyGroup>
  ...
</Project>

Build Configuration

A default Visual Studio project has two build configurations: Debug and Release (see Build Configurations). In an MSBuild project file, these are configured using properties:

<Project ... >
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">
      Debug
    </Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <OutputType>WinExe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>WpfApplication1</RootNamespace>
    <AssemblyName>WpfApplication1</AssemblyName>
    <FileAlignment>512</FileAlignment>
    <WarningLevel>4</WarningLevel>
    ...
  </PropertyGroup>
  ...
</Project>

The current build configuration is specified by the Configuration property:

<Project ... >
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">
      Debug
    </Configuration>
    ...
  </PropertyGroup>
  ...
</Project>

Source Code File Association

Visual Studio maintains an association between related source code files, such as markup and code-behind files. This allows Visual Studio to visualize the association in the Visual Studio Solution Explorer window:

Solution Explorer screen shot

The association between related source code files is made using DependentUpon and SubType metadata:

<Project ... >
  ...
  <ItemGroup>
    <ApplicationDefinition Include="App.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </ApplicationDefinition>
    <Page Include="Window1.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </Page>
    <Compile Include="App.xaml.cs">
      <DependentUpon>App.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="Window1.xaml.cs">
      <DependentUpon>Window1.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
  </ItemGroup>
  ...
</Project>

In this project, App.xaml (markup) is associated with App.xaml.cs (code-behind), and Window1.xaml (markup) is associated with Window1.xaml.cs (code-behind).

Default Project Property, Resource, and Settings Management

Visual Studio allows you to visually edit the properties of a Visual Studio project. The majority of these affect the build process and are stored in the Visual Studio-managed Visual Studio project file. The Windows Presentation Foundation (WPF) project templates also generate files to provide strongly-typed settings and resources support. All are shown in the following figure:

Solution Explorer screen shot

These are managed by the MSBuild project file using the following:

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
  ...
  <ItemGroup>
    <Compile Include="Properties\AssemblyInfo.cs">
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="Properties\Settings.Designer.cs">
      <AutoGen>True</AutoGen>
      <DependentUpon>Settings.settings</DependentUpon>
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
    </Compile>
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
      <SubType>Designer</SubType>
    </EmbeddedResource>
    <None Include="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
    </None>
    <AppDesigner Include="Properties\" />
  </ItemGroup>
  ...
</Project>

Building an MSBuild Project for WPF

MSBuild projects can be built from either a command prompt or Visual Studio.

Building an MSBuild Project for WPF from the Command Prompt

MSBuild projects can be built by calling msbuild.exe from either the Windows command prompt or the Windows Software Development Kit (SDK) command prompt.

Building a Project

To build an MSBuild project, you execute msbuild.exe, passing the file name of the desired MSBuild project:

msbuild.exe msbuildprojectfile.proj

Building a Language-Specific Project Generated by Visual Studio

Language-specific MSBuild project files generated by Visual Studio:

  • Have a relevant file extension (.csproj, .vbproj).

  • Include a language-specific target (Microsoft.CSharp.targets, Microsoft.VisualBasic.targets).

The following shows how to build a C# project from the command prompt:

msbuild.exe VSGeneratedProjectFileForCSharp.csproj

The following shows how to build a Visual Basic project from the command prompt:

msbuild.exe VSGeneratedProjectFileForVisualBasic.vbproj

Building a Solution Generated by Visual Studio

msbuild.exe will also build solution files (.sln) that were generated by Visual Studio:

msbuild.exe VSGeneratedSolutionFile.sln

Building an MSBuild Project for WPF in Visual Studio

If you are using Visual Studio, you don't need to build your projects and solutions from the command prompt; Visual Studio allows you to do both from the IDE.

Building a Project in Visual Studio

To build a project in Visual Studio, right-click the project in the Solution Explorer window and choose Build.

Building a Solution in Visual Studio

To build a solution, do any of the following:

  • Press F6 to build the solution.

  • Press F5 to start debugging the solution.

  • Choose Build | Build Solution.

  • Choose Debug | Start Debugging.

  • Choose Debug | Start Without Debugging.

Doing any of these for either a project or a solution causes Visual Studio to execute msbuild.exe to build the appropriate MSBuild files.

Windows Presentation Foundation Build Pipeline

When a WPF project is built, the combination of language-specific and WPF-specific targets are invoked. The process of executing these targets is called the build pipeline, and the key steps are illustrated by the following figure.

WPF build process

These steps are described in more detail in the following sections.

Pre-Build Initializations

Before building, MSBuild determines the location of important tools and libraries, including the following:

  • The .NET Framework.

  • The Windows SDK directories.

  • The location of WPF reference assemblies.

  • The property for the assembly search paths.

The reference assembly directory (%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.0\) is the first location where assemblies are looked for. During this step, the build process also initializes the various properties and item groups and performs any required cleanup work.

Resolving References

The build process locates and binds the assemblies required to build the application project. This logic is contained in the ResolveAssemblyReference task. All assemblies declared as Reference in the project file are provided to the task along with information on the search paths and metadata on assemblies already installed on the system. The task looks up assemblies and uses the installed assembly's metadata to filter out those core WPF assemblies that need not show up in the output manifests. This is done to avoid redundant information in the ClickOnce manifests. For example, since PresentationFramework.dll can be considered representative of an application built on and for the WPF and moreover since all WPF assemblies exist at the same location on every machine that has the .NET Framework installed, there is no need to include all information on all .NET Framework reference assemblies in the manifests.

Markup Compilation—Pass 1

In this step, XAML files are parsed and compiled so that the runtime does not spend time parsing XML and validating property values. The compiled XAML file is pre-tokenized so that, at run time, loading it should be much faster than loading a XAML file.

During this step, the following activities take place for every XAML file that is a Page build item:

  1. The XAML file is parsed by the markup compiler.

  2. A compiled representation is created for that XAML and copied to the obj\Release folder.

  3. A CodeDOM representation of a new partial class is created and copied to the obj\Release folder.

In addition, a language-specific code file is generated for every XAML file. For example, for a Page1.xaml page in a Visual Basic project, a Page1.g.vb is generated; for a Page1.xaml page in a C# project, a Page1.g.cs is generated. The ".g" in the file name indicates the file is generated code that has a partial class declaration for the top-level element of the markup file (such as Page or Window). The class is declared with the partial modifier in C# (Extends in Visual Basic) to indicate there is another declaration for the class elsewhere, usually in the code-behind file Page1.xaml.cs.

The partial class extends from the appropriate base class (such as Page for a page) and implements the System.Windows.Markup.IComponentConnector interface. The IComponentConnector interface has methods to initialize a component and connect names and events on elements in its content. Consequently, the generated code file has a method implementation like the following:

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);
}

By default, markup compilation runs in the same AppDomain as the MSBuild engine. This provides significant performance gains. This behavior can be toggled with the AlwaysCompileMarkupFilesInSeparateDomain property. This has the advantage of unloading all reference assemblies by unloading the separate AppDomain.

Markup Compilation—Pass 2

Not all XAML pages are compiled during pass 1 of markup compilation. XAML files that have locally defined type references (references to types defined in code elsewhere in the same project) are exempt from compilation at this time. This is because those locally defined types exist only in source and have not yet been compiled. In order to determine this, the parser uses heuristics that involve looking for items such as x:Name in the markup file. When such an instance is found, that markup file’s compilation is postponed until the code files have been compiled, after which, the second markup compilation pass processes these files.

File Classification

The build process puts output files into different resource groups based on which application assembly they will be placed in. In a typical nonlocalized application, all data files marked as Resource are placed in the main assembly (executable or library). When UICulture is set in the project, all compiled XAML files and those resources specifically marked as language-specific are placed in the satellite resource assembly. Furthermore, all language-neutral resources are placed in the main assembly. In this step of the build process, that determination is made.

The ApplicationDefinition, Page, and Resource build actions in the project file can be augmented with the Localizable metadata (acceptable values are true and false), which dictates whether the file is language-specific or language-neutral.

Core Compilation

The core compile step involves compilation of code files. This is orchestrated by logic in the language-specific targets files Microsoft.CSharp.targets and Microsoft.VisualBasic.targets. If heuristics have determined that a single pass of the markup compiler is sufficient, then the main assembly is generated. However, if one or more XAML files in the project have references to locally defined types, then a temporary .dll file is generated so the final application assemblies may be created after the second pass of markup compilation is complete.

Manifest Generation

At the end of the build process, after all the application assemblies and content files are ready, the ClickOnce manifests for the application are generated.

The deployment manifest file describes the deployment model: the current version, update behavior, and publisher identity along with digital signature. This manifest is intended to be authored by administrators who handle deployment. The file extension is .xbap (for XAML browser applications (XBAPs)) and .application for installed applications. The former is dictated by the HostInBrowser project property and as a result the manifest identifies the application as browser-hosted.

The application manifest (an .exe.manifest file) describes the application assemblies and dependent libraries and lists permissions required by the application. This file is intended to be authored by the application developer. In order to launch a ClickOnce application, a user opens the application's deployment manifest file.

These manifest files are always created for XBAPs. For installed applications, they are not created unless the GenerateManifests property is specified in the project file with value true.

XBAPs get two additional permissions over and above those permissions assigned to typical Internet zone applications: WebBrowserPermission and MediaPermission. The WPF build system declares those permissions in the application manifest.

Incremental Build Support

The WPF build system provides support for incremental builds. It is fairly intelligent about detecting changes made to markup or code, and it compiles only those artifacts affected by the change. The incremental build mechanism uses the following files:

  • An $(AssemblyName)_MarkupCompiler.Cache file to maintain current compiler state.

  • An $(AssemblyName)_MarkupCompiler.lref file to cache the XAML files with references to locally defined types.

The following is a set of rules governing incremental build:

  • The file is the smallest unit at which the build system detects change. So, for a code file, the build system cannot tell if a type was changed or if code was added. The same holds for project files.

  • The incremental build mechanism must be cognizant that a XAML page either defines a class or uses other classes.

  • If Reference entries change, then recompile all pages.

  • If a code file changes, recompile all pages with locally defined type references.

  • If a XAML file changes:

    • If XAML is declared as Page in the project: if the XAML does not have locally defined type references, recompile that XAML plus all XAML pages with local references; if the XAML has local references, recompile all XAML pages with local references.

    • If XAML is declared as ApplicationDefinition in the project: recompile all XAML pages (reason: each XAML has reference to an Application type that may have changed).

  • If the project file declares a code file as application definition instead of a XAML file:

    • Check if the ApplicationClassName value in the project file has changed (is there a new application type?). If so, recompile the entire application.

    • Otherwise, recompile all XAML pages with local references.

  • If a project file changes: apply all preceding rules and see what needs to be recompiled. Changes to the following properties trigger a complete recompile: AssemblyName, IntermediateOutputPath, RootNamespace, and HostInBrowser.

The following recompile scenarios are possible:

  • The entire application is recompiled.

  • Only those XAML files that have locally defined type references are recompiled.

  • Nothing is recompiled (if nothing in the project has changed).

See Also

Concepts

Deploying a WPF Application (WPF)

Pack URIs in Windows Presentation Foundation

Windows Presentation Foundation Application Resource, Content, and Data Files

Other Resources

Windows Presentation Foundation MSBuild Reference

Change History

Date

History

Reason

July 2008

Added information about the SplashScreen build property.

SP1 feature change.