Wix toolset примеры: не так страшен черт, как Windows installer / Хабр
21.06.2023 Разное
Работа с файлами в инсталяторах на WiX Toolset
В прошлой статье про проекты инсталяторов в Visual Studio я привел маленький пример, позволяющий добавить в MSI только exe файл нашего проекта. Сегодня предлагаю посмотреть как добавить другие файлы из проекта.
В прошлый раз мы остановились на том, что задали вот такую настройку для добавления файлов в проект (привожу текстом, т.к. в прошлый раз была картинка):
<Fragment>
<ComponentGroup Id=»ProductComponents» Directory=»INSTALLFOLDER»>
<Component Id=»ProductComponent»>
<File Source=»$(var.EyeOfSauron.TargetPath)» />
</Component>
</ComponentGroup>
</Fragment>
Теперь добавим копирование файла конфигурации и, например, dll которая используется в этом проекте и распространяется методом копирования.
<Component Id="EyeOfSauron.exe.config"> <File Source="$(var.EyeOfSauron.TargetDir)\EyeOfSauron.exe.config" /> </Component> <Component Id="Hardcodet.Wpf.TaskbarNotification.dll"> <File Source="$(var.EyeOfSauron.TargetDir)\Hardcodet.Wpf.TaskbarNotification.dll" /> </Component>
Обратите внимание, что вместо TargetPath (указывает на exe файл) используется TargetDir (папка куда выполнялось построение).
Ну и весьма полезный список поддерживаемых переменных (в скобках примеры того, что там в ней может быть):
$(var.MyProject.Configuration) — конфигурация проекта (Debug или Release)
$(var.MyProject.FullConfiguration) — кроме конфигурации содержит еще и платформу под которую идет компиляция (Debug|AnyCPU)
$(var.MyProject.ProjectDir) — путь до папки с проектом (C:\users\myusername\Documents\Visual Studio 2013\Projects\MyProject\)
$(var. MyProject.ProjectExt) — спорная переменная, которая позволяет получить расширение файла с проектом (.csproj)
$(var.MyProject.ProjectFileName) — имя файла проекта (MyProject.csproj)
$(var.MyProject.ProjectName) — аналогично предыдущему, но без расширения (MyProject)
$(var.MyProject.ProjectPath) — путь к файлу проекта (C:\users\myusername\Documents\Visual Studio 2013\Projects\MyProject\MyApp.csproj)
$(var.MyProject.TargetDir) — как раз эту переменную я использовал в примере выше (C:\users\myusername\Documents\Visual Studio 2013\Projects\MyProject\bin\Debug\)
$(var.MyProject.TargetExt)
$(var.MyProject.TargetFileName) — имя собираемого файла (MyProject.exe)
$(var.MyProject.TargetName) — аналогично предыдущему, но без расширения (MyProject)
$(var.MyProject.TargetPath) — тоже есть в примере, это полный путь до результата сборки (C:\users\myusername\Documents\Visual Studio 2013\Projects\MyProject\bin\Debug\MyProject. exe)
$(var.SolutionDir) — папка в которой лежит решение (C:\users\myusername\Documents\Visual Studio 2013\Projects\MySolution\)
$(var.SolutionExt) — расширение решения (.sln)
$(var.SolutionFileName) — имя файла решения (MySolution.sln)
$(var.SolutionName) — аналогично предыдущему, но без расширения (MySolution)
$(var.SolutionPath) — Полное имя решения (C:\users\myusername\Documents\Visual Studio 2013\Projects\MySolution\MySolution.sln)
Воспользоваться этим можно, например, вот так:
if $(var.EyeOfSauron.Configuration) = "Debug" ?> <Component Id="EyeOfSauron.exe.config"> <File Name="EyeOfSauron.exe.config" Source="$(var.EyeOfSauron.ProjectDir)\App.Debug.config" /> </Component> else?> <Component Id="EyeOfSauron.exe.config"> <File Source="$(var.EyeOfSauron.TargetDir)\EyeOfSauron.exe.config" /> </Component> endif?>
Что здесь интересного:
1. Применяем if $(var.EyeOfSauron.Configuration) = «Debug» ?>, для того, чтобы проанализировать в какой конфигурации у нас идет Build.
2. Строим путь до файла в папке проекта: Source=»$(var.EyeOfSauron.ProjectDir)\App.Debug.config»
3. Меняем имя файла при копировании его в инсталятор:
Ну и заканчивая с файлами, как создавать вложенные папки при развертывании и как поместить в них файлы. Допустим, у нашего проекта есть папка Images и в ней лежит иконка, которую мы хотим скопировать. Вот так:
В файле Product.wxd кроме использованного выше фрагмента (Fragment) есть, если помните из предыдущей статьи и вот такой фрагмент:
<Fragment> <Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="ProgramFilesFolder"> <Directory Id="INSTALLFOLDER" Name="EyeOfSauron" /> </Directory> </Directory> </Fragment>
Правим его следующим образом:
<Fragment> <Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="ProgramFilesFolder"> <Directory Id="INSTALLFOLDER" Name="EyeOfSauron"> <Directory Id="Images" Name="Images" /> </Directory> </Directory> </Directory> </Fragment>
Добавляем в информацию о продукте новую ComponentGroupRef:
<Feature Id="ProductFeature" Title="EyeOfSauron" Level="1"> <ComponentGroupRef Id="ProductComponents" /> <ComponentGroupRef Id="Icons" /> </Feature>
Ну и в уже знакомый нам фрагмент добавляем новый ComponentGroup:
<ComponentGroup Id="Icons" Directory="Images"> <Component Id="fire_eye_alien. ico" > <File Id="fire_eye_alien.ico" Source="$(var.EyeOfSauron.ProjectDir)\Images\fire_eye_alien.ico" KeyPath="yes"/> </Component> </ComponentGroup>
Все, папка с файлом будут доступны в развернутом приложении.
Ну и весь пример, а то вдруг чего забыл в процессе:
xml version="1.0" encoding="UTF-8"?> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <Product Id="*" Name="EyeOfSauron" Language="1033" Version="1.0.0.0" Manufacturer="Life" UpgradeCode="fb4e9c90-2572-4d75-a219-02713e72ad0e"> <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" /> <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." /> <MediaTemplate /> <Feature Id="ProductFeature" Title="EyeOfSauron" Level="1"> <ComponentGroupRef Id="ProductComponents" /> <ComponentGroupRef Id="Icons" /> </Feature> </Product> <Fragment> <Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="ProgramFilesFolder"> <Directory Id="INSTALLFOLDER" Name="EyeOfSauron"> <Directory Id="Images" Name="Images" /> </Directory> </Directory> </Directory> </Fragment> <Fragment> <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER"> <Component Id="ProductComponent"> <File Source="$(var.EyeOfSauron.TargetPath)" /> </Component> if $(var.EyeOfSauron.Configuration) = "Debug" ?> <Component Id="EyeOfSauron.exe.config"> <File Name="EyeOfSauron.exe.config" Source="$(var.EyeOfSauron.ProjectDir)\App.Debug.config" /> </Component> else?> <Component Id="EyeOfSauron.exe.config"> <File Source="$(var.EyeOfSauron.TargetDir)\EyeOfSauron.exe.config" /> </Component> endif?> <Component Id="Hardcodet.Wpf.TaskbarNotification.dll"> <File Source="$(var.EyeOfSauron.TargetDir)\Hardcodet.Wpf.TaskbarNotification.dll" /> </Component> </ComponentGroup> <ComponentGroup Id="Icons" Directory="Images"> <Component Id="fire_eye_alien.ico" > <File Id="fire_eye_alien.ico" Source="$(var.EyeOfSauron.ProjectDir)\Images\fire_eye_alien.ico" KeyPath="yes"/> </Component> </ComponentGroup> </Fragment> </Wix>
Создание инсталлятора с помощью WiX.
Часть 1. Простой инсталляторПри написании коммерческого софта часто встает вопрос о способе его поставки конечному пользователю. Тут можно рассмотреть несколько вариантов: мы можем поставлять программное обеспечение в виде набора файлов, копируя его на рабочие места пользователей и затем, настраивая вручную, можем разворачивать программное обеспечение с помощью облачных сервисов, например Windows Azure. Также мы можем предоставлять пользователю пакет программ в виде инсталлятора, который включает в себя этап настройки приложений.
Как показывает опыт, в данный момент мало заказчиков решаются использовать в своем рабочем процессе облачные сервисы. С этим связан ряд причин, начиная от обеспечения безопасности хранимой информации и заканчивая стоимостью готовых решений. Что касается поставки в виде набора файлов, то этот вариант также не является удобным. Представим, что мы разворачиваем сервер приложений. В данном случае при ручной поставке нам необходимо совершить множество рутинных ручных действий: скопировать файлы, настроить конфигурации, зарегистрировать и запустить службу Windows, настроить правила брандмауэра и т.
д. При всем этом ручная настройка является чем-то сродни искусству, которое требует большого внимания и концентрации.Исходя из всего выше сказанного, мне кажется, что самым удобным способом поставки готового приложения будет подготовка инсталлятора. Да, для этого понадобится приложить некоторые усилия и потратить время, но это решение позволит сэкономить время и нервы службы внедрения на этапе развертывания.
Сейчас на рынке присутствует множество коммерческих решений для создания инсталляторов. Например, InstallShield, InstallAware, InnoSetup, NSIS и прочие. Мы на своем проекте решили остановиться на пакете Microsoft WiX по причине его бесплатности. Технология WiX (Windows Installer XML) – это набор инструментов для упрощения процесса создания дистрибутива на базе MSI.
С этой статьи я хочу начать цикл постов о написании инсталлятора с помощью WiX, начиная с простого инсталлятора, потом рассмотреть встраивание собственных форм, написание расширений и закончить встраиванием процесса подготовки инсталлятора в конвейер поставки на базе TFS.
Итак, мы будем писать инсталлятор для простого сервиса WCF, который будет хоститься как служба Windows. Исходники этого приложения входят в примеры к статье и располагаются в проекте InstallingApplication.
В данной статье мы подготовим простейший инсталлятор, который будет содержать следующий набор окон:
- Приветствие
- Лицензионное соглашение
- Выбор папки установки
- Начало установки.
Сначала скачиваем и устанавливаем WiX. После установки в
Visual Studio будут добавлены новые шаблоны проектов Windows Installer XML. Выбираем шаблон Setup Project. В моем примере проект будет называться ApplicationInstaller.
Изначально будет создан один файл Product.wxs. Это основной файл, в котором описывается поведение инсталлятора.
Настроим поддержку русского языка. Для этого в секции Product изменим значение атрибута Language на 1049. Это магическое число укажет, что инсталлятор должен использовать русскую локаль. Затем откроем свойства проекта и во вкладке Build укажем значение «ru-RU» для параметра Culture to build (без кавычек). На данном этапе этого будет достаточно, чтобы наш инсталлятор научился говорить по-русски.
После этого подчистим файл Product.wxs. Удалим все секции Fragment и MajorUpdate. Пока они нам не нужны.
Добавим описание директорий, куда будем инсталлировать наше приложение.
<Directory Name="SourceDir"> <Directory> <Directory Name="ApplicationServer" /> </Directory> <Directory> <Directory Name="ApplicationServer" /> </Directory> </Directory>
Тэг Directory определяет путь для установки. Directory Id=”TARGETDIR” – корневой элемент для всех папок, в которые будет инсталлироваться наше приложение. Directory Id=”ProgramFilesFolder» указывает на папку Program Files. Directory Id=”INSTALLLOCATION” – это папка с именем ApplicationServer в папке Program Files. Эта иерархия описывает расположение нашей программы по умолчанию.
Второе описание иерархии папок указывает расположение ярлыков к нашему приложению. Id=”ProgramMenuFolder” ссылается на папку меню Пуск. В меню пуск будет создана папка ApplicationServer.
Добавим файлы к папке установки. Для этого создадим файл Files.wxs и запишем в него следующее содержимое.
<DirectoryRef FileSource="..\..\InstallingApplication\ApplicationWindowsService\bin\Debug\"> <Component Id ="ProductComponents" DiskId="1" Guid="{B65CDCEE-7130-4759-A8E8-16D84717CCF2}"> <File Name="ApplicationService.Common.dll"/> <File Name="ApplicationWindowsService.exe"/> <File Name="ApplicationWindowsService.exe.config"/> <File Name="log4net.dll"/> </Component> </DirectoryRef>
Секция DirectoryRef ссылается на описанную ранее папку c идентификатором INSTALLLOCATION. Атрибут FileSource содержит путь, по которому необходимо искать все файлы, добавляемые в инсталлятор. В данном случае указан относительный путь до скомпилированных модулей нашей службы.
Секция Component включает описание устанавливаемых файлов. Для задания значения атрибуту Guid рекомендую использовать тулзу Create Guid из Visual Studio (Меню Tools – Create GUID). Далее секция File описывает конкретный устанавливаемый файл. Секция для корректной работы должна содержать уникальный идентификатор Id (в моем случае он совпадает с именем файла). Атрибут Name указывает, что файл нужно искать по заданному имени в директории FileSource.
Теперь давайте опишем ярлыки, которые мы будем создавать. В меню Пуск мы создадим два ярлыка: для запуска приложения и для деинсталляции. На практике для серверных приложений не стоит указывать ярлык для запуска, и здесь я это привожу только для примера. Создадим файл Shortcuts.wxs и добавим в него следующее.
<DirectoryRef> <Component Guid="{DFA97C7E-E565-44D2-8D1E-7AB1E52ADB01}"> <Shortcut Name="Application Server" Description="Start application server" Target="[INSTALLLOCATION]ApplicationWindowsService.exe" WorkingDirectory="INSTALLLOCATION"/> <Shortcut Name="Uninstall application serrver" Description="Uninstall application serrver" Target="[System64Folder]msiexec.exe" Arguments="/x [ProductCode]"/> <RemoveFolder On="uninstall"/> <RegistryValue Root="HKCU" Key="Software\MyCompany\ApplicationServer" Name="installed" Type="integer" Value="1" KeyPath="yes"/> </Component> </DirectoryRef>
Секция Shortcut указывает на создание ярлыка. Первая секция создает ярлык для нашего приложения с указанием в качестве рабочей директории папки установки. Вторая секция Shortcut немного интересней. Она создает ярлык для деинсталляции нашего приложения. Для этого используется программа msiexec с ключом /x.
Секция RemoveFolder говорит о том, что при деинсталляции необходимо удалить папку с ярлыками из меню пуск. Оставшаяся секция RegistyValue необходима для того, чтобы удаление заработало. Я сильно не вдавался в подробности, но без создания этого ключа деинсталляция работать не будет.
На этом почти все. Осталось описать все наши компоненты в секции Feature файла Product.wxs. Этот элемент может быть использован, когда нам необходимо дать пользователю возможность выбора, что устанавливать, а что нет. В условиях нашей задачи ничего не говорилось о возможности выбора, но, несмотря на это нам необходимо привязать описанные секции Component к одной единственной Feature.
<Feature Title="ApplicationInstaller" Level="1"> <ComponentRef /> <ComponentRef/> </Feature>
Напоследок допишем еще две строки для подключения графического интерфейса к нашему инсталлятору. К проекту инсталлятора необходимо добавить ссылку на сборку WixUIExtension из поставки WiX. Эта библиотека расширений позволит подключить интерфейс пользователя.
<Property Value="INSTALLLOCATION"></Property> <UIRef/>
Все! Теперь после компиляции мы получим файл ApplicationInstaller.msi, который и является нашим готовым инсталлятором.
На этом все. Все исходники можно взять здесь.
Дополнительные источники:
- Книга по WiX
- Еще одна книга по WiX от нашего соотечественника.
Набор инструментов WiX / Примеры
#
| Резюме▾
| Веха▾
| Статус▾
| Владелец▾
| Создано▾
| Обновлено▾
| |
---|---|---|---|---|---|---|---|
33 | Требуется установщик Javafx из образца wixtoolset | Нет | открыть | 2014-08-18 | 2014-08-18 | ||
31 | платформа версии 4. 5 | Нет | открыть | WiX-сборка | 2013-05-12 | 2013-05-12 | |
30 | ожидаемые значения для ManagedRuntimeVersion и ManagedPipelineMode | Нет | открыть | WiX-сборка | 2013-05-12 | 2013-05-12 | |
29 | Попытка использовать WiX для установки документации в новую структуру каталогов | Нет | открыть | 2013-02-07 | 2015-01-17 | ||
28 | Изменить значение в XML с помощью параметров командной строки с помощью установщика WIX | Нет | открыть | 2013-01-17 | 2013-01-17 | ||
27 | Управляемый загрузчик — как передавать переменные для управления полной установкой | Нет | открыть | 2013-01-01 | 2013-01-01 | ||
26 | Локализация установки и пропуск экрана лицензионного соглашения | Нет | открыть | 2011-09-12 | 2015-02-26 | ||
23 | Полный путь обновления, распространяемый с помощью Wix | Нет | открыть | 2010-11-19 | 2012-09-15 | ||
22 | мультиязычность wix | Нет | открыть | 2010-10-19 | 2015-02-15 | ||
21 | Как: в модуле использовать ComponentGroup из фрагмента | Нет | открыть | 2009 г. -11-13 | 2012-09-15 | ||
20 | Как: Нагрев — Установить файл/@Source с препроцессором Var | Нет | открыть | 2009-04-24 | 2012-09-15 | ||
19 | Как: Нагрев — Подавить корневой каталог | Нет | открыть | 2009-04-24 | 2014-08-25 | ||
18 | Как: Нагрев — Укажите DirectoryRef/@Id | Нет | открыть | 2009-04-24 | 2012-09-15 | ||
17 | Как: Нагрев — Укажите группу компонентов | Нет | открыть | 2009-04-24 | 2012-09-15 | ||
16 | Как: Подавить предупреждения ICE | Нет | открыть | 21 июля 2008 г. | 2012-09-15 | ||
15 | Как: Подготовьте программу установки к поддержке основных обновлений | Нет | открыть | 21 июля 2008 г. | 2012-09-15 | ||
14 | Как настроить существующие диалоговые окна пользовательского интерфейса WiX | Нет | открыть | 21 июля 2008 г. | 2012-09-15 | ||
13 | Как добавить диалоговое окно в последовательность пользовательского интерфейса WiX | Нет | открыть | 21 июля 2008 г. | 2012-09-15 | ||
11 | Как: Автоматически установить версию MSI из исполняемого файла | Нет | открыть | 21 июля 2008 г. | 2012-09-15 | ||
8 | Автоматизировать версию в проекте | Нет | открыть | 2007-10-11 | 2013-06-03 | ||
7 | Рабочее использование CrystalReports11_5_NET_2005.msm | Нет | открыть | 2007-04-30 | 2012-09-15 | ||
6 | Пример запуска службы при необходимости установки | Нет | открыть | 2007-03-19 | 2012-09-15 | ||
5 | Учебникнеправильно предполагает инструменты в PATH | Нет | открыть | 27 февраля 2007 г. | 2012-09-15 | ||
4 | пример загрузчика | Нет | открыть | 2005-12-12 | 2012-09-15 | ||
3 | Создание структуры каталогов на другом диске | Нет | открыть | 2005-08-12 | 2012-09-15 |
- Номер билета
- Краткое содержание
- Веха
- Положение дел
- Владелец
- Создатель
- Созданный
- Обновлено
- Этикетки
(относится только к этой странице)
1 2 > >> (Страница 1 из 2)
Как добавить файл в установщик
Установка файлов является наиболее фундаментальным аспектом любого установщика, и обычно это то, что в первую очередь побуждает людей создавать установщик. Изучение того, как поместить файл на диск с использованием передовых методов установщика Windows, не только обеспечивает удобство сопровождения в будущем, но и позволяет создавать исправления позже, если это необходимо.
Шаг 1. Определите структуру каталогов
У установщиков часто бывает много файлов, которые нужно установить в несколько мест на диске. Чтобы улучшить читаемость файла WiX, рекомендуется сначала определить каталоги установки, прежде чем перечислять файлы, которые вы будете устанавливать. Каталоги определяются с помощью элемента Directory и описывают иерархию папок, которые вы хотели бы видеть на целевой машине. В следующем примере определяется каталог для установки основного исполняемого файла приложения.
Элемент с идентификатором TARGETDIR требуется Windows Installer и является корнем всех структур каталогов для вашей установки. Каждый проект WiX будет иметь этот элемент каталога. Второй элемент с идентификатором ProgramFilesFolder использует предопределенное свойство установщика Windows для ссылки на папку Program Files на компьютере пользователя. В большинстве случаев это разрешается до c:\Program Files\ . Третий элемент каталога создает папку вашего приложения в Program Files, и ему присваивается идентификатор APPLICATIONROOTDIRECTORY для последующего использования в проекте WiX. Идентификатор написан заглавными буквами, чтобы сделать его общедоступным свойством, которое можно установить из пользовательского интерфейса или через командную строку.
Результатом этих тегов является папка c:\Program Files\My Application Name на целевом компьютере.
Шаг 2. Добавьте файлы в пакет установщика
Файл добавляется в установщик с помощью двух элементов: элемент Component для указания атомарной единицы установки и элемент File для указания файла, который необходимо установить.
Элемент component описывает набор ресурсов (обычно это файлы, записи реестра и ярлыки), которые необходимо установить как единое целое. Это не зависит от того, состоит ли набор элементов из логической функции, которую пользователь может выбрать для установки, что обсуждается на шаге 3. Хотя это может показаться не таким уж важным, когда вы впервые создаете свой установщик, компоненты играют решающую роль, когда вы решаете создать патчи позже.
В общем, вы должны ограничиться одним файлом для каждого компонента. Установщик Windows предназначен для поддержки тысяч компонентов в одном установщике, поэтому, если у вас нет веской причины, используйте один файл для каждого компонента. Каждый компонент должен иметь свой уникальный идентификатор GUID . Несоблюдение этих двух основных правил может привести ко многим проблемам в будущем, когда дело доходит до обслуживания.
В следующем примере структура каталогов, определенная на шаге 1, используется для установки двух файлов: исполняемого файла приложения и файла документации.
<Источник файла="MySourceFiles\MyApplication.exe" KeyPath="yes" Checksum="yes"/>
html" KeyPath="yes"/>
Элемент DirectoryRef используется для ссылки на структура каталогов, созданная на шаге 1. При ссылке на каталог APPLICATIONROOTDIRECTORY файлы будут установлены в c:\program files\My Application Name папка. Под DirectoryRef находятся два элемента Component, по одному для каждого из двух файлов, которые будут установлены. Это соответствует наилучшей практике использования одного компонента в файле. Каждому элементу компонента присваивается идентификатор и идентификатор. Идентификатор используется для ссылки на компонент позже в проекте WiX. Guid используется позже для исправлений и должен быть уникальным для каждого компонента. Сведения о создании идентификаторов GUID см. в разделе Как создать идентификатор GUID.
Под каждым компонентом находится элемент File, который выполняет фактическую работу по упаковке исходных файлов в программу установки. Идентификатор используется для ссылки на файл в другом месте проекта WiX. Атрибут Source указывает расположение файла на вашем компьютере, поэтому WiX может найти его и встроить в установщик.
Для атрибута KeyPath задано значение yes, чтобы указать установщику Windows, что этот конкретный файл следует использовать для определения того, установлен ли компонент. Если вы не установите атрибут KeyPath, WiX будет просматривать дочерние элементы под компонентом в последовательном порядке и пытаться автоматически выбрать один из них в качестве ключевого пути. Разрешение WiX автоматически выбирать ключевой путь может быть опасным, поскольку добавление или удаление дочерних элементов в компоненте может непреднамеренно привести к изменению ключевого пути, что может привести к проблемам при установке. Как правило, всегда следует устанавливать для атрибута KeyPath значение yes, чтобы гарантировать, что путь к ключу не изменится непреднамеренно, если вы в будущем обновите свою авторскую установку.
Для атрибута Checksum должно быть задано значение yes для исполняемых файлов, имеющих значение контрольной суммы в заголовке файла (обычно это верно для всех исполняемых файлов), и используется установщиком Windows для проверки правильности файла при повторной установке. .
Шаг 3. Попросите установщика Windows установить файлы
После определения структуры каталогов и списка файлов, которые необходимо упаковать в установщик, последним шагом будет указание установщику Windows фактически установить файлы. Для этого используется элемент Feature, где вы разбиваете свой установщик на логические части, которые пользователь может установить независимо. В следующем примере создается одна функция, которая устанавливает исполняемый файл приложения и документацию из шага 2.
Функция получает идентификатор. Если вы используете последовательность пользовательского интерфейса установщика, которая включает выбор функции, атрибут Title содержит текст, отображаемый в пользовательском интерфейсе для функции. Атрибут Уровень должен быть установлен на 1, чтобы включить установку функции по умолчанию.
Элемент ComponentRef используется для ссылки на компоненты, созданные на шаге 2, с помощью атрибута Id.
Leave a Comment