Поделиться через


Построение приложения WPF

Приложения Windows Presentation Foundation (WPF) могут быть построены как исполняемые файлы (.exe), библиотеки (.dll) или как комбинация обоих типов сборки .NET Framework. В этом разделе приведены основные сведения о построении приложений WPF и описаны основные шаги процесса построения.

В этом разделе содержатся следующие подразделы.

  • Построение приложения WPF
  • Конвейер построения WPF
  • Поддержка инкрементного построения
  • Связанные разделы

Построение приложения WPF

Компиляцию приложения WPF можно выполнять следующими способами.

Конвейер построения WPF

Когда проект WPF собран, вызывается комбинация файлов целей, зависимых от конкретного языка и от WPF. Процесс выполнения этих файлов целей называется конвейер построения, его ключевые шаги показаны в следующей схеме.

Процесс построения WPF

Инициализации перед построением

Перед построением MSBuild определяет расположение важных средств и библиотек, в том числе следующих:

  • .NET Framework.

  • Каталоги Windows SDK.

  • Расположение сборок ссылок WPF.

  • Свойство для путей поиска сборки.

MSBuild в первую очередь выполняет поиск сборок в каталоге базовых сборок (%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.0\). На этом шаге процесс построения также инициализирует различные свойства и группы элементов, а также выполняет все необходимые работы по очистке.

Разрешение ссылок

Процесс построения находит и привязывает сборки, которые требуются для построения проекта приложения. Логика процесса содержится в задаче ResolveAssemblyReference. Все сборки, объявленные в файле проекта как Reference, предоставляются задаче вместе с информацией о путях поиска и метаданными о сборках, уже установленных в системе. Задача ищет сборки и использует метаданные установленной сборки для фильтрации этих основных сборок WPF, которые не должны отображаться в манифесте выходных данных. Это делается, чтобы избежать избыточных данных в манифесте ClickOnce. Например, так как PresentationFramework.dll может считаться представителем приложения, построенного на и для WPF и, кроме того, поскольку все сборки WPF расположены в одном и том же месте на каждом компьютере, на котором установлен .NET Framework, нет необходимости включать в манифесты все сведения о всех сборках ссылок .NET Framework.

Компиляция разметки — этап 1

На этом шаге файлы XAML синтаксически разбираются и компилируются, чтобы среда выполнения далее не тратила время на разбор XML и проверку значений свойств. Скомпилированный файл XAML заранее размечен, так что во время выполнения его загрузка занимает намного меньше времени, чем загрузка файла XAML.

На этом шаге для каждого файла XAML, являющегося элементом, построенным Page, выполняются следующие действия:

  1. Файл XAML разбирается компилятором разметки.

  2. Для этого XAML создается скомпилированное представление, затем оно копируется в папку obj\Release.

  3. Создается представление CodeDOM нового частичного класса, затем оно копируется в папку obj\Release.

Кроме того, для каждого файла XAML создается зависящий от языка файл кода. Например, для страницы Page1.xaml в проекте Visual Basic создается файл Page1.g.vb, а для той же страницы в проекте C# создается файл Page1.g.cs. ".g" в имени файла показывает, что файл является созданным кодом с объявлением частичного класса для верхнеуровневого элемента файла разметки (например, Page или Window). Класс объявлен в C# с модификатором partial (в Visual Basic с модификатором Extends), означающим, что где-то в другом месте есть другое объявление класса, обычно в файле кода программной части Page1.xaml.cs.

Частичный класс расширяется от соответствующего базового класса (например, Page для страницы) и реализует интерфейс System.Windows.Markup.IComponentConnector. В интерфейсе IComponentConnector есть методы инициализации компонента и связывания имен и событий элемента в его содержимом. Следовательно, в созданном файле кода есть реализация метода, как, например, показано далее:

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

По умолчанию компиляция разметки выполняется в том же AppDomain, что и ядро MSBuild. Это обеспечивает значительное преимущество в производительности. Такое поведение может быть переключено с помощью свойства AlwaysCompileMarkupFilesInSeparateDomain. Так можно получить преимущество при выгрузке все сборок ссылок при выгрузке отдельного AppDomain.

Компиляция разметки — этап 2

Не все страницы XAML компилируются на этапе 1 компиляции разметки. Файлы XAML, для которых локально определены ссылки на типы (ссылки на типы, определенные в коде в другом месте того же проекта), исключаются из компиляции на этом этапе. Это происходит потому, что эти локально определенные типы существуют только в исходном коде и еще не скомпилированы. Чтобы определить это, синтаксический анализатор использует эвристику, вызывающую поиск элементов, таких как x:Name, в файле разметки. Если такой экземпляр обнаруживается, компиляция этого файла разметки откладывается до тех пор, пока файлы кода не будут скомпилированы, после чего второй этап компиляции разметки будет обрабатывать эти файлы.

Классификация файлов

Процесс построения распределяет выходные файлы в различные группы ресурсов, основанные на том, в какой сборке приложения они будут расположены. В обыкновенном нелокализованном приложении все файлы данных, отмеченные как Resource, располагаются в главной сборке (исполняемом файле или библиотеке). Когда в проекте задан UICulture, все скомпилированные файлы XAML и ресурсы, специально отмеченные как специфичные для конкретного языка, помещаются в сопутствующую сборку ресурсов. Кроме того, все нейтральные для языка ресурсы помещаются в основную сборку. На этом шаге процесса построения производится определение.

Действия построения ApplicationDefinition, Page и Resource в файле проекта могут быть дополнены метаданными Localizable (допустимые значения — true и false), которые указывают, является ли файл зависящим или не зависящим от языка.

Основная компиляция

На этапе основной компиляции осуществляется компиляция файлов кода. Это происходит по логике, содержащейся в специфичных для языка файлах целей Microsoft.CSharp.targets и Microsoft.VisualBasic.targets.. Если эвристика определила, что первого этапа компилятора разметки достаточно, то создается основная сборка. Тем не менее, если один или несколько файлов XAML в проекте имеют ссылки на локально определенные типы, то затем создается временный DLL-файл, чтобы по завершении второго этапа компиляции разметки могли быть созданы окончательные сборки приложения.

Создание манифеста

В конце процесса построения, при готовности всех сборок приложения и файлов содержимого, для приложения создаются манифесты ClickOnce.

Файл манифеста развертывания описывает модель развертывания: текущую версию, поведение обновления и идентификатор издателя вместе с цифровой подписью. Этот манифест должен быть написан администраторами, управляющими развертыванием. Расширение файла: XBAP (для XAML browser applications (XBAPs)) и APPLICATION для установленных приложений. Первое расширение определяется свойством HostInBrowser проекта, и в результате манифест идентифицирует приложение как приложение, размещенное в обозревателе.

Манифест приложения (файл .exe.manifest) описывает сборки приложения и зависимые библиотеки и перечисляет разрешения, необходимые для приложения. Этот файл должен быть написан разработчиком приложения. Чтобы запустить приложение ClickOnce, пользователь открывает файл манифеста развертывания приложения.

Эти файлы манифеста всегда создаются для XBAPs. Для установленных приложений они не создаются, если в файле проекта свойство GenerateManifests не имеет значение true.

XBAPs получают два дополнительных и более высокоприоритетных разрешения, чем присвоенные обычным приложениям зоны "Интернет": WebBrowserPermission и MediaPermission. Система построения WPF объявляет эти разрешения в манифесте приложения.

Поддержка инкрементного построения

Система построения WPF обеспечивает поддержку инкрементного построения. Она довольно умело обнаруживает изменения в разметке и коде, и она компилирует только те фрагменты, на которые влияют изменения. Механизм инкрементного построения использует следующие файлы:

  • Файл $(AssemblyName)_MarkupCompiler.Cache для поддержания текущего состояния компилятора.

  • Файл $(AssemblyName)_MarkupCompiler.lref для кэширования файлов XAML со ссылками на локально определенные типы.

Ниже приведен набор правил, управляющих инкрементным построением:

  • Файл является наименьшей единицей, в которой система построения обнаруживает изменения. Таким образом, для файла кода система построения не может определить, был ли изменен тип или добавлен код. То же самое касается и файлов проекта.

  • Механизм инкрементного построения должен знать, определяет ли страница XAML класс или использует другие классы.

  • При изменении Reference перекомпилируются все страницы.

  • При изменении файла кода перекомпилируются все страницы с локально определенными ссылками типа.

  • При изменении файла XAML:

    • Если XAML объявлен в проекте как Page: если XAML не имеет локально определенных ссылок типа, перекомпилируется этот XAML плюс все страницы XAML с локальными ссылками; если XAML имеет локальные ссылки, перекомпилируются все страницы XAML с локальными ссылками.

    • Если XAML объявлен в проекте как ApplicationDefinition: перекомпилируются все страницы XAML (поскольку во всех XAML есть ссылка на тип Application, который возможно был изменен).

  • Если файл проекта объявляет файл кода как определение приложения вместо файла XAML:

    • Проверяется, изменилось ли значение ApplicationClassName в файле проекта (есть ли новый тип приложения?). Если это так, перекомпилируется все приложение.

    • В противном случае перекомпилируются все страницы XAML с локальными ссылками.

  • При изменении файла проекта применяются все вышеперечисленные правила и проверяется, что должно быть перекомпилировано. Изменения следующих свойств приводят к полной перекомпиляции: AssemblyName, IntermediateOutputPath, RootNamespace и HostInBrowser.

Возможны следующие сценарии перекомпиляции:

  • Перекомпилируется все приложение.

  • Перекомпилируются только те файлы XAML, в которых есть локально определенные ссылки типа.

  • Ничего не перекомпилируется (если в проекте ничего не было изменено).

См. также

Основные понятия

Развертывание приложений WPF

URI типа "pack" в WPF

Ресурсы, Содержимое и Файлы данных WPF-приложения

Другие ресурсы

Справочные сведения о WPF для MSBuild

Журнал изменений

Дата

Журнал

Причина

Ноябрь 2010 г.

Добавлен отсутствующий пример Visual Basic.

Исправление ошибки содержимого.