Building a Windows Presentation Foundation Application

To build any non-trivial Windows Presentation Foundation (WPF) application, developers will need to rely on Microsoft build engine (MSBuild). This topic covers why MSBuild is required for WPF applications, and how to both create and build MSBuild project files. 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 using Command Line Compilation
  • Build a WPF Application Using MSBuild
  • MSBuild Project Files for WPF
  • Creating an MSBuild Project for WPF using Visual Studio
  • Building an MSBuild Project for WPF
  • The Windows Presentation Foundation Build Pipeline
  • Incremental Build Support
  • Related Topics

Building a WPF Application using Command Line Compilation

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

  • An application definition file (app.cs).

  • A window (mainwindow.cs).

This application can be built using the C# command line compiler, csc.exe, using the following command:

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 is used to specify the name of compiled executable application (WPFApplication.exe).

  • The /target parameter is used to specify the type of application that is compiled (a Microsoft Windows executable).

  • The C# source code files are specified (app.cs and mainwindow.cs)

  • The /reference parameter is used to identify the .NET Framework 3.0 assemblies with types that are used from the source code.

While this application is composed of two source code files, command line compilation can be used to build applications with more complexity (see Building from the Command Line (CSharp)). However, command line compilation does not support the compilation of WPF applications that include Extensible Application Markup Language (XAML) markup source code files. Furthermore, command-line compilation is not robust enough to support the full range of build requirements that are required by typical WPF applications, including configuration management and ClickOnce application and deployment manifest generation. To support the more complex build requirements of WPF applications, WPF integrates with and extends the MSBuild.

Build a WPF Application Using MSBuild

MSBuild is a robust and extensible build technology that is included with the .NET Framework 3.0, including the assemblies that are listed in the following table:

Assembly Description

Microsoft.Build.Engine.dll

Is the common build engine responsible for reading and processing MSBuild project files.

Microsoft.Build.Tasks.dll

Implements MSBuild functionality that is common to all MSBuild projects, including invocation of command-line compilers such as the C# compiler, csc.exe.

Microsoft.Build.Utilities.dll

Exposes a set of utility classes that can be used to extend MSBuild with custom build functionality.

Microsoft.Build.Framework.dll

Contains a set of interfaces that define how MSBuild functionality interacts with the MSBuild engine.

Microsoft.Build.Conversion.dll

Contains classes that convert legacy Microsoft Visual Studio .NET 2002 and Microsoft Visual Studio .NET 2003 project files to the Microsoft Visual Studio 2005 MSBuild format.

See MSBuild Reference for more information on the MSBuild assemblies.

These assemblies form the core of the MSBuild engine. To build an application, MSBuild engine needs the following information:

  • Source code file references.

  • Dependent assembly references.

  • Configuration details.

  • Build requirements.

Collectively, these details describe an MSBuild project, and are contained by a project file. An MSBuild project file is an XML file that conforms to a custom schema provided by MSBuild (see MSBuild Project File Schema Reference). WPF integrates with and extends MSBuild project files by leveraging the extensibility of the MSBuild project file schema and the build engine.

MSBuild Project Files for WPF

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 is simple, but contains the elements that are common to most MSBuild project files, including the Project tag, properties, targets, and tasks.

The Project Element

As per 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 contains MSBuild version information and is the location from which the MSBuild engine starts processing a project file.

Properties

Properties are variables that are used to both configure an MSBuild project and provide build-specific information to the MSBuild engine. MSBuild project properties are always contained within a PropertyGroup element, as shown here:

<Project ... >

<PropertyGroup>

<AssemblyName>WPFApplication</AssemblyName>

<OutputType>winexe</OutputType>

</PropertyGroup>

...

</Project>

There are a variety of properties that are common to all application types, such as AssemblyName and OutputType, and are described in MSBuild Properties. The MSBuild properties that are specific to WPF are listed in the following table:

Table 1: WPF-Specific MSBuild Project Properties

Property Description

OutputType

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

  • Winexe: Build an executable assembly (.exe). Windows Application (WPF) and XAML Browser Applications (WPF) (XBAPs) are configured with this output type.

  • Library: Build a library assembly (.dll). Custom Control Libraries (WPF) is configured with this output type.

HostInBrowser

Specifies whether a WPF application is hosted in a browser eg a XAML Browser Application (WPF) (XBAP). HostInBrowser can be one of the following values:

  • true: creates a XAML Browser Application (WPF) (XBAP), which includes the following:

    • The main application assembly (.exe).

    • All referenced assemblies that are configured to be copied to the build output folder.

    • A deployment manifest (applicationName.xbap).

    • An application manifest (applicationName.exe.manifest).

  • false: creates a Windows Application (WPF).

If HostInBrowser is true, the OutputType must be winexe.

Install

Specifies whether a XAML Browser Application (WPF) (XBAP) is installed on the client. Install can be either true or false, and must be the opposite of the HostInBrowser value.

GenerateManifests

Specifies whether a Windows Application (WPF) will be published using ClickOnce deployment:

  • true: Creates ClickOnce manifests, including a deployment manifest (applicationName.application), and an application manifest (applicationName.exe.manifest).

  • false: only creates the application executable (.exe).

GenerateManifests is only used when Install property has value 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.

NoteNote:

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

Items

Items are MSBuild inputs that are used during the build process. MSBuild project items are contained within an ItemGroup element. The most common types of items are assembly references and code files:

<Project ... >

...

<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, while source code files are configured as Compile items. There are a variety of items that are common to all application types, including Reference and Compile. See MSBuild Items for information on common MSBuild items.

The MSBuild items that are specific to WPF are listed in the following table:

Table 2: WPF-Specific MSBuild Items

Property Description

ApplicationDefinition

Identifies the XAML markup file that contains the application definition (a piece of XAML markup whose root element is Application). ApplicationDefinition is mandatory when Install is true and the OutputType is winexe. There can only be one ApplicationDefinition per MSBuild project.

Page

Identifies a XAML markup file that will be converted to binary and compiled into an application assembly. The most common XAML markup files that are specified as Page items are those that have Window, Page, ResourceDictionary, and FlowDocument as their top-level elements.

Resource

Identifies an application data file that is compiled into an application assembly and can be uniquely identified by either a pack URI or a relative URI. The UICulture property (described earlier) impacts Resource items.

Content

Identifies an application data file that will be distributed alongside an application and can be uniquely identified by either a pack URI or a relative URI. Metadata that describes the application data file is compiled into the application.

Targets

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

<Project ... >

...

<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 3.0 are installed in the following location:

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

The language-specific target contains the logic to build 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.

Microsoft.WinFX.targets is the target that performs WPF-specific build work, including XAML markup compilation, manifest generation for XBAP applications, and processing WPF resource and content application data files.

Tasks

A task is a .NET Framework 3.0 class that performs a specific build-related action, and on or more tasks are combined by targets to perform a specific type of build; when the MSBuild engine processes a target, it actually 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, while the tasks that are specific to WPF are implemented by the PresentationBuildTasks assembly.

In general, targets provide the necessary support to build all standard WPF applications. However, it is possible to use alternative combinations of tasks when more specific build behavior is required, For example:

<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:\WinFXNative"

WinFXWowPath="c:\WinFXWowNative" />

</Target>

<Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" />

</Project>

In this example, the GetWinFXPath task is used to detect the native path to the .NET Framework 3.0 runtime, which is dependent on whether the task is executing on a 64 bit processor.

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

Windows Presentation Foundation MSBuild Project Samples

The Windows Software Development Kit (SDK) comes with several example MSBuild project files that represent the most common types of Windows Presentation Foundation (WPF) applications:

Creating an MSBuild Project for WPF using Visual Studio

While an MSBuild project file for a WPF application can be manually created, Visual Studio automatically generates them when a new WPF application is created using one of the Visual Studio project templates. For example, the Windows Application (WPF) project template generates the following project file (for C#):

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

<PropertyGroup>

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

<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>

<ProjectGuid>{C4B3F872-D678-40EC-B4EA-62D8BA7A2131}</ProjectGuid>

<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

<RootNamespace>WPFWindowsApplication</RootNamespace>

<AssemblyName>WPFWindowsApplication</AssemblyName>

<WarningLevel>4</WarningLevel>

<OutputType>winexe</OutputType>

<ApplicationVersion>1.0.0.*</ApplicationVersion>

<BootstrapperEnabled>false</BootstrapperEnabled>

<MinFrameworkVersionRequired>3.0</MinFrameworkVersionRequired>

</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

<DebugSymbols>true</DebugSymbols>

<DebugType>full</DebugType>

<Optimize>false</Optimize>

<OutputPath>.\bin\Debug\</OutputPath>

<DefineConstants>DEBUG;TRACE</DefineConstants>

</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">

<DebugSymbols>false</DebugSymbols>

<Optimize>true</Optimize>

<OutputPath>.\bin\Release\</OutputPath>

<DefineConstants>TRACE</DefineConstants>

</PropertyGroup>

<ItemGroup>

<Reference Include="System" />

<Reference Include="WindowsBase" />

<Reference Include="PresentationCore" />

<Reference Include="PresentationFramework" />

</ItemGroup>

<ItemGroup>

<ApplicationDefinition Include="App.xaml" />

<Page Include="Window1.xaml" />

<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" />

<EmbeddedResource Include="Properties\Resources.resx">

<Generator>ResXFileCodeGenerator</Generator>

<LastGenOutput>Resources.cs</LastGenOutput>

<SubType>Designer</SubType>

</EmbeddedResource>

<Compile Include="Properties\Resources.cs">

<AutoGen>True</AutoGen>

<DependentUpon>Resources.resx</DependentUpon>

</Compile>

<None Include="Properties\Settings.settings">

<Generator>SettingsSingleFileGenerator</Generator>

<LastGenOutput>Settings.cs</LastGenOutput>

</None>

<Compile Include="Properties\Settings.cs">

<AutoGen>True</AutoGen>

<DependentUpon>Settings.settings</DependentUpon>

</Compile>

<AppDesigner Include="Properties\" />

</ItemGroup>

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

<Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" />

</Project>

The name of the generated MSBuild project file extension incorporates the source code language. For C# projects, the file extension is .csproj, and is .vbproj for Visual Basic projects.

The project file is considerably larger than the previous examples, which is partly due to several additional properties. However, most of the extra build information is Visual Studio-specific, and includes project configuration, build configuration, source code file association, and default project property, resource, and settings management.

Project Configuration

The project configuration details include a unique identifier for the project and a unique identifier for the project type:

<Project ... >

<PropertyGroup>

<ProjectGuid>{C4B3F872-D678-40EC-B4EA-62D8BA7A2131}</ProjectGuid>

<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

...

</PropertyGroup>

...

</Project>

Build Configuration

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

<Project ... >

<PropertyGroup>

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

...

</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

<DebugSymbols>true</DebugSymbols>

<DebugType>full</DebugType>

<Optimize>false</Optimize>

<OutputPath>.\bin\Debug\</OutputPath>

<DefineConstants>DEBUG;TRACE</DefineConstants>

</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">

<DebugSymbols>false</DebugSymbols>

<Optimize>true</Optimize>

<OutputPath>.\bin\Release\</OutputPath>

<DefineConstants>TRACE</DefineConstants>

</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 that association in the Visual Studio Solution Explorer window, shown here:

Solution Explorer screen shot

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

<Project ... >

...

<ItemGroup>

<ApplicationDefinition Include="App.xaml" />

<Page Include="Window1.xaml" />

<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 default .NET Framework 3.0 settings and resources support. All are shown in the following figure:

Solution Explorer screen shot

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

<Project ... >

...

<ItemGroup>

<Compile Include="Properties\AssemblyInfo.cs" />

<EmbeddedResource Include="Properties\Resources.resx">

<Generator>ResXFileCodeGenerator</Generator>

<LastGenOutput>Resources.cs</LastGenOutput>

<SubType>Designer</SubType>

</EmbeddedResource>

<Compile Include="Properties\Resources.cs">

<AutoGen>True</AutoGen>

<DependentUpon>Resources.resx</DependentUpon>

</Compile>

<None Include="Properties\Settings.settings">

<Generator>SettingsSingleFileGenerator</Generator>

<LastGenOutput>Settings.cs</LastGenOutput>

</None>

<Compile Include="Properties\Settings.cs">

<AutoGen>True</AutoGen>

<DependentUpon>Settings.settings</DependentUpon>

</Compile>

<AppDesigner Include="Properties\" />

</ItemGroup>

...

</Project>

Building an MSBuild Project for WPF

You can build an MSBuild projects using the command line or Visual Studio.

Building an MSBuild Project for WPF from the Command Line

MSBuild projects can be built from either the Windows command line or the Windows Software Development Kit (SDK) command window using msbuild.exe, which is included with Microsoft .NET Framework version 3.0. To build a MSBuild project, you execute msbuild.exe, passing the filename of the desired MSBuild project:

msbuild.exe msbuildprojectfile.proj

msbuild.exe will also process both MSBuild project files (.csproj or .vbproj) and solution files (.sln) that were generated by Visual Studio:

msbuild.exe VSGeneratedProjectFileForCSharp.csproj

msbuild.exe VSGeneratedProjectFileForVisualBasic.vbproj

msbuild.exe VSGeneratedSolutionFile.sln

Building an MSBuild Project for WPF in Visual Studio

In Visual Studio, you build a project by doing the following:

  • Right-click the project in the Solution Explorer window and choose Build.

In Visual Studio, you build a solution, which contains one or more projects, by doing one of the following:

  • Press F6 to build the solution.

  • Press F5 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.

The 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 topics.

Pre-Build Initializations

Prior to building anything, the MSBuild engine determines the location of important tools and libraries, including the following

  • The Microsoft .NET Framework version 3.0.

  • The Windows Software Development Kit (SDK) directories.

  • The location of WPF reference assemblies.

  • The property for the assembly search paths.

The reference assembly directory (eg %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 3.0 installed, there is no need to include all information on all .NET Framework 3.0 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 etc. The compiled XAML file is pre-tokenized so, at runtime, 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 eg for Page1.xaml page in a Visual Basic project, a Page1.g.vb is generated, and, 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 (eg Page, Window, etc). 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.Serialization.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:

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 us significant performance gains. This behavior can be toggled with the AlwaysCompileMarkupFilesInSeparateDomain property. The latter one has the advantage of unloading all reference assemblies by unloading the separate AppDomain.

Pass 2 of Markup Compilation

Not all XAML pages are compiled at during pass 1 of markup compilation. XAML files that have locally-defined type references (ie 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 x:Name etc. 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 will process 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 non-localized application, all data files marked as Resource are placed in the main assembly (executable or library, as the case may be). When UICulture is set in the project, all compiled XAML files along with those resources specifically marked as language-specific, will be placed in the satellite resource assembly. Furthermore, all language-neutral resources will be 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 ie 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 once the second pass of markup compilation is complete.

Manifest generation

At the tail 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, 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, 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. These additional permissions are: 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 to compile only those artifacts impacted by the change. The incremental build mechanism uses

  • 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 lowest granularity 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 code file changes, recompile all pages with locally-defined type references.

  • If XAML file changes:

    • If XAML is declared as Page in the project: if XAML does not have locally-defined type references, recompile that XAML plus all XAML pages with local references; if 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 Application type which may have changed).

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

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

    • Or recompile all XAML pages with local references.

  • If project file changes: apply all above rules and see what needs to be recompiled. Changes to the following properties trigger a full-blown re-compile: AssemblyName, IntermediateOutputPath, RootNamespace, HostInBrowser.

The following recompile scenarios exist:

  1. The entire application is recompiled.

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

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

See Also

Concepts

Deploying a Windows Presentation Foundation Application
Pack URIs in Windows Presentation Foundation
Windows Presentation Foundation Application Data Files

Other Resources

MSBuild Concepts
MSBuild Reference
C# Compiler Options
Visual Basic Compiler