Для начала — что такое 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 с ним мы и будем работать. В моем случае файл выглядел следующим образом:

<?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 — фрагменты и инклуды