Для начала — что такое WiX? Технология WiX (Windows Installer XML) представляет собой набор инструментов и спецификаций упрощающих процесс создания дистрибутивов на базе MSI (Microsoft Installer). Если объяснять проще то это обертка вокруг MSI с человеческим лицом.
На мой взгляд изучать проще всего на простых примерах. В данной статье я приведу пример простейшего инсталлятора.
Для начала поставим условия задачи — необходимо создать установочный дистрибутив, который будет содержать следующие диалоги:
Приветствие

Лицензионное соглашение

Выбор директории

Начало установки

Для создания дистрибутива нам понадобится сам WiX, послед��юю версию которого всегда можно скачать на Source Forge. На данный момент последняя версия 3.5.0828.0.
Необходимо скачать и установить:
1. ProjectAggregator2.msi — нужен, для того, чтобы установить Votive (находится внутри дистрибутива номер 2). Который, в свою очередь, является дополнением для Visual Studio, облегчающим процесс работы с WiX (подсветка синтаксиса, IntelliSense).
2. Wix35.msi или Wix35_x64.msi (в зависимости от платформы)
3. Русский языковой файл
Итак, скачали, установили, запускаем Visual Studio. Меню File -> New Project, если все установлено правильно — появился новый раздел Windows Installer XML. Выбираем шаблон проекта Setup Project, вводим название проекта (я оставил как есть SetupProject1).

Проект будет состоять из одного файла Product.wxs с ним мы и будем работать. В моем случае файл выглядел следующим образом:
Для начала настроим внешний вид и добавим поддержку русского языка.
Начнем с добавления русского языка. Для этого:
1. В ключе Product изменяем 1033 на 1049
2. В свойствах проекта (правой клавишей по названию проекта в Solution Explorer -> Properties), закладка Build, в поле Cultures to build вставляем ru-RU
3. Добавляем к проекту (правой клавишей по названию проекта в Solution Explorer -> Add -> Existing Item) файл WixUI_ru-ru.wxl (из архива WixUI_ru-ru.v3.zip)
В сгенерированном проекте нет ни одного диалогового окна. Существуют два варинта добавления диалоговых окон — создавать самостоятельно, либо воспользоваться готовым набором диалоговых окон.
Мы пойдем вто��ым путем, начинать знакомство лучше с простого. Для этого необходимо добавить ссылку на WixUIExtension.dll (правой клавишей по названию проекта в Solution Explorer -> Add Reference — открываем папку, в которую был установлен WiX, подкаталог bin)
Ссылку добавили, указываем какой набор мы будем использовать, в конце раздела Product добавим
WixVariable Id=«WixUILicenseRtf» — указывает на путь к файлу лицензии (речи о нем пока не шло, добавили сразу, чтобы два раза не ходить).
WixUI_InstallDir — готовый набор диалоговых окон. Данный набор включает все необходимые нам диалоги. Помимо него так же существуют наборы WixUI_Advanced, WixUI_Mondo, WixUI_FeatureTree, WixUI_InstallDir, WixUI_Minimal.
Приготовления закончены, можно приступать к редактированию файла установки. Для начала посмотрим, что нам нагенерила студия:
Ключ Product — описывает свойства продукта.
Id — идентификатор продукта, уникальный GUID.
Name — название продукта
Language — язык пакета установки
Version — версия продукта
Manufacturer — производитель
UpgradeCode — уникальный GUID
Чтобы упростить себе жизнь определим некоторые переменные. Для чего — название продукта, например, не раз может встречаться в скрипте, если нам захочется его изменить придется искать его по всему скрипту и менять на новое. Чтобы избежать этого определим переменную, которая будет содержать название продукта и, в случае необходимости, будем менять только ее. Над разделом Product добавим:
Теперь заменим значение параметров ключа Product на переменные:
Определимся теперь с тем куда мы будем устанавливать наш продукт.
Ключ Directory — определяет путь для установки.
Directory Id=«TARGETDIR» корневой элемент для всех папок, которые будут использоваться для установки проекта.
Directory Id=«ProgramFilesFolder» папка Program Files (на что указывает Id=«ProgramFilesFolder»).
Directory Id=«INSTALLLOCATION» папка с именем SetupProject1 в папке Program Files. Заменим сразу Name=«SetupProject1» на Name="$(var.ProductName)"
Добавим файлы в пакет установки. Для этого сначала добавим устанавливаемые компоненты. Следуя совету «Remove the comments around this Component» уберем комментарии с Component внутри целевой папки и добавим туда, например, калькулятор.
Установка компонента невозможна без включения его в одну из Feature (если честно не уверен как в данном случае можно перевести этот термин на русский язык). Этот элемент может быть использован когда нам необходимо дать пользователю возможность выбора, что устанавливать, а что нет. В условиях нашей задачи ничего не говорилось о возможности выбора, но несмотря на это нам необходимо привязать описанный Component к одной единственной Feature:
Осталось добавить ярлык в меню Пуск.
Сначала укажем, что мы собираемся работать с папкой меню Пуск и хотим там создать папку с именем нашей программы, содержащую ярлык на калькулятор.
В раздел Directory Id=«TARGETDIR», где-нибудь в конце добавляем:
Начинаем разбираться:
Directory Id=«ProgramMenuFolder» — указывает на директорию, в которой содержатся ярлыки меню Пуск.
Directory Id=«ApplicationProgramsFolder» — папка нашей программы в меню Пуск
Component — компонент, содержащий ярлык (не забыть включить его в Feature)
Shortcut — собственно ярлык к калькулятору
Финальная версия файла должна выглядеть так:
Делаем Build, запускаем, проверяем результат.
Где еще почитать
Страница проекта
Alex Shevchuk: From MSI to WiX (в основном на английском, но есть немного на русском)
WiX Tutorial
wixwiki
Продолжение Часть 2 — фрагменты и инклуды
На мой взгляд изучать проще всего на простых примерах. В данной статье я приведу пример простейшего инсталлятора.
Для начала поставим условия задачи — необходимо создать установочный дистрибутив, который будет содержать следующие диалоги:
Приветствие

Лицензионное соглашение

Выбор директории

Начало установки

Для создания дистрибутива нам понадобится сам WiX, послед��юю версию которого всегда можно скачать на Source Forge. На данный момент последняя версия 3.5.0828.0.
Необходимо скачать и установить:
1. ProjectAggregator2.msi — нужен, для того, чтобы установить Votive (находится внутри дистрибутива номер 2). Который, в свою очередь, является дополнением для Visual Studio, облегчающим процесс работы с WiX (подсветка синтаксиса, IntelliSense).
2. Wix35.msi или Wix35_x64.msi (в зависимости от платформы)
3. Русский языковой файл
Итак, скачали, установили, запускаем Visual Studio. Меню File -> New Project, если все установлено правильно — появился новый раздел Windows Installer XML. Выбираем шаблон проекта Setup Project, вводим название проекта (я оставил как есть SetupProject1).

Проект будет состоять из одного файла Product.wxs с ним мы и будем работать. В моем случае файл выглядел следующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="b7bc7c6f-9a4e-4973-be84-eca8e3427c97" Name="SetupProject1" Language="1033" Version="1.0.0.0" Manufacturer="SetupProject1" UpgradeCode="06a81104-1e30-463d-87e1-e8a79b4c682a">
<Package InstallerVersion="200" Compressed="yes" />
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="SetupProject1">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<!-- <Component Id="ProductComponent" Guid="b11556a2-e066-4393-af5c-9c9210187eb2"> -->
<!-- TODO: Insert files, registry keys, and other resources here. -->
<!-- </Component> -->
</Directory>
</Directory>
</Directory>
<Feature Id="ProductFeature" Title="SetupProject1" Level="1">
<!-- TODO: Remove the comments around this ComponentRef element and the Component above in order to add resources to this installer. -->
<!-- <ComponentRef Id="ProductComponent" /> -->
</Feature>
</Product>
</Wix>
* This source code was highlighted with Source Code Highlighter.Для начала настроим внешний вид и добавим поддержку русского языка.
Начнем с добавления русского языка. Для этого:
1. В ключе Product изменяем 1033 на 1049
2. В свойствах проекта (правой клавишей по названию проекта в Solution Explorer -> Properties), закладка Build, в поле Cultures to build вставляем ru-RU
3. Добавляем к проекту (правой клавишей по названию проекта в Solution Explorer -> Add -> Existing Item) файл WixUI_ru-ru.wxl (из архива WixUI_ru-ru.v3.zip)
В сгенерированном проекте нет ни одного диалогового окна. Существуют два варинта добавления диалоговых окон — создавать самостоятельно, либо воспользоваться готовым набором диалоговых окон.
Мы пойдем вто��ым путем, начинать знакомство лучше с простого. Для этого необходимо добавить ссылку на WixUIExtension.dll (правой клавишей по названию проекта в Solution Explorer -> Add Reference — открываем папку, в которую был установлен WiX, подкаталог bin)
Ссылку добавили, указываем какой набор мы будем использовать, в конце раздела Product добавим
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" ></Property>
<WixVariable Id="WixUILicenseRtf" Overridable="yes" Value="License.rtf"/>
<UIRef Id="WixUI_InstallDir"/>
* This source code was highlighted with Source Code Highlighter.WixVariable Id=«WixUILicenseRtf» — указывает на путь к файлу лицензии (речи о нем пока не шло, добавили сразу, чтобы два раза не ходить).
WixUI_InstallDir — готовый набор диалоговых окон. Данный набор включает все необходимые нам диалоги. Помимо него так же существуют наборы WixUI_Advanced, WixUI_Mondo, WixUI_FeatureTree, WixUI_InstallDir, WixUI_Minimal.
Приготовления закончены, можно приступать к редактированию файла установки. Для начала посмотрим, что нам нагенерила студия:
Ключ Product — описывает свойства продукта.
Id — идентификатор продукта, уникальный GUID.
Name — название продукта
Language — язык пакета установки
Version — версия продукта
Manufacturer — производитель
UpgradeCode — уникальный GUID
Чтобы упростить себе жизнь определим некоторые переменные. Для чего — название продукта, например, не раз может встречаться в скрипте, если нам захочется его изменить придется искать его по всему скрипту и менять на новое. Чтобы избежать этого определим переменную, которая будет содержать название продукта и, в случае необходимости, будем менять только ее. Над разделом Product добавим:
<?define ProductName="SetupProject1" ?>
<?define ProductVersion="1.0.0.0" ?>
<?define ProductCode="b7bc7c6f-9a4e-4973-be84-eca8e3427c97"?>
<?define UpgradeCode="06a81104-1e30-463d-87e1-e8a79b4c682a"?>
<?define Manufacturer="MyCompany"?>
* This source code was highlighted with Source Code Highlighter.Теперь заменим значение параметров ключа Product на переменные:
<Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1049" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
* This source code was highlighted with Source Code Highlighter.Определимся теперь с тем куда мы будем устанавливать наш продукт.
Ключ Directory — определяет путь для установки.
Directory Id=«TARGETDIR» корневой элемент для всех папок, которые будут использоваться для установки проекта.
Directory Id=«ProgramFilesFolder» папка Program Files (на что указывает Id=«ProgramFilesFolder»).
Directory Id=«INSTALLLOCATION» папка с именем SetupProject1 в папке Program Files. Заменим сразу Name=«SetupProject1» на Name="$(var.ProductName)"
Добавим файлы в пакет установки. Для этого сначала добавим устанавливаемые компоненты. Следуя совету «Remove the comments around this Component» уберем комментарии с Component внутри целевой папки и добавим туда, например, калькулятор.
<Component Id="ProductComponent" Guid="b11556a2-e066-4393-af5c-9c9210187eb2">
<File Id='Calc' DiskId='1' Source='C:\WINDOWS\system32\calc.exe'/>
</Component>
* This source code was highlighted with Source Code Highlighter.Установка компонента невозможна без включения его в одну из Feature (если честно не уверен как в данном случае можно перевести этот термин на русский язык). Этот элемент может быть использован когда нам необходимо дать пользователю возможность выбора, что устанавливать, а что нет. В условиях нашей задачи ничего не говорилось о возможности выбора, но несмотря на это нам необходимо привязать описанный Component к одной единственной Feature:
<Feature Id="ProductFeature" Title="$(var.ProductName)" Level="1">
<ComponentRef Id="ProductComponent" />
</Feature>
* This source code was highlighted with Source Code Highlighter.Осталось добавить ярлык в меню Пуск.
Сначала укажем, что мы собираемся работать с папкой меню Пуск и хотим там создать папку с именем нашей программы, содержащую ярлык на калькулятор.
В раздел Directory Id=«TARGETDIR», где-нибудь в конце добавляем:
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="$(var.ProductName)">
<Component Id="ApplicationShortcutCalc" Guid="4CEBD68F-E933-47f9-B02C-A4FC69FDB551">
<Shortcut Id="ShortcutCalc"
Name="Calc"
Description="$(var.ProductName)"
Target="[INSTALLLOCATION]Calc.exe"
WorkingDirectory="INSTALLLOCATION"/>
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\$(var.Manufacturer)\$(var.ProductName)" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
</Directory>
</Directory>
* This source code was highlighted with Source Code Highlighter.Начинаем разбираться:
Directory Id=«ProgramMenuFolder» — указывает на директорию, в которой содержатся ярлыки меню Пуск.
Directory Id=«ApplicationProgramsFolder» — папка нашей программы в меню Пуск
Component — компонент, содержащий ярлык (не забыть включить его в Feature)
Shortcut — собственно ярлык к калькулятору
Финальная версия файла должна выглядеть так:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define ProductName="SetupProject1" ?>
<?define ProductVersion="1.0.0.0" ?>
<?define ProductCode="b7bc7c6f-9a4e-4973-be84-eca8e3427c97"?>
<?define UpgradeCode="06a81104-1e30-463d-87e1-e8a79b4c682a"?>
<?define Manufacturer="MyCompany"?>
<Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1049" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
<Package InstallerVersion="200" Compressed="yes" />
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="$(var.ProductName)">
<Component Id="ProductComponent" Guid="b11556a2-e066-4393-af5c-9c9210187eb2">
<File Id='Calc' DiskId='1' Source='C:\WINDOWS\system32\calc.exe'/>
</Component>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="$(var.ProductName)">
<Component Id="ApplicationShortcutCalc" Guid="4CEBD68F-E933-47f9-B02C-A4FC69FDB551">
<Shortcut Id="ShortcutCalc"
Name="Calc"
Description="$(var.ProductName)"
Target="[INSTALLLOCATION]Calc.exe"
WorkingDirectory="INSTALLLOCATION"/>
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\$(var.Manufacturer)\$(var.ProductName)" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="ProductFeature" Title="SetupProject1" Level="1">
<ComponentRef Id="ProductComponent" />
<ComponentRef Id="ApplicationShortcutCalc" />
</Feature>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" ></Property>
<WixVariable Id="WixUILicenseRtf" Overridable="yes" Value="License.rtf"/>
<UIRef Id="WixUI_InstallDir"/>
</Product>
</Wix>
* This source code was highlighted with Source Code Highlighter.Делаем Build, запускаем, проверяем результат.
Где еще почитать
Страница проекта
Alex Shevchuk: From MSI to WiX (в основном на английском, но есть немного на русском)
WiX Tutorial
wixwiki
Продолжение Часть 2 — фрагменты и инклуды
