Создаем свой первый инсталлятор на Windows Installer XML (WiX) v3.0 в Visual Studio.

Как создать WiX – проект в Visual Studio

После установки необходимых компонентов для работы WiX в Visual Studio, можно приступать к созданию WiX – проекта.

  1. Выберите в меню File, затем New, затем Project…

  2. В дереве типов проектов выберите WiX, затем WiX Project и назовите его “FirstWixProject”.

В результате получите проект FirstWixProject и файл Product.wxs, который содержит начальный вариант кода установки.

Пример:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="PUT-GUID-HERE"
           Name="FirstWixProject"
           Language="1033"
           Version="1.0.0.0"
           Manufacturer="FirstWixProject"
           UpgradeCode="PUT-GUID-HERE">
    <Package InstallerVersion="300" Compressed="yes" />

    <Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLLOCATION" Name="FirstWixProject">
          <!-- TODO: Remove the comments around this Component element -->
          <!--and the ComponentRef below in order to add resources to this installer. -->
          <!-- <Component Id="ProductComponent" Guid="PUT-GUID-HERE"> -->
            <!-- TODO: Insert files, registry keys, and other resources here. -->
          <!-- </Component> -->
          </Directory>
      </Directory>
    </Directory>

    <Feature Id="ProductFeature" Title="FirstWixProject" 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>

В сгенерированном файле на месте фразы “PUT-GUID-HERE” уже будут стоят конкретные значения, но в дальнейшем GUID’ы необходимо будет генерировать и добавлять там где это потребуется. Генерировать GUID’ы можно, например, с помощью программы giudgen.

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

Но некоторые изменения коснутся атрибутов Wix и Product; напрмер, для большей ясности измените имя продукта (Product Name) на “My Application”, а имя производителя (Product Manufacturer) на “My Manufacturer”. В результате вы должны получить:

  <Product Id="PUT-GUID-HERE"
           Name="My Application"
           Language="1033"
           Version="1.0.0.0"
           Manufacturer="My Manufacturer"
           UpgradeCode="PUT-GUID-HERE">

Файлу Product.wxs требуется некоторая дополнительная информация, чтобы компиляция прошла успешно. Все что необходимо сделать для этого – это добавить файл.

Как добавить файлы

Поскольку WiX – проект является таким же проектом как и все остальные, то его можно добавлять в Solution с проектами, для которых и создается инсталлятор. После того, как WiX – проект добавлен в Solution, необходимо добавить к нему ссылки на те проекты, чьи файлы вы собираетесь включать в инсталлятор. В дальнейшем предполагаем, что вы добавили ссылку на проект MyApplication.

При добавлении каждого файла будет необходимо указать путь к этому файлу. И проще всего это будет сделать, ссылаясь на проект его содержащий.

Процесс добавления файла состоит из следующих шагов:

  1. Объявление директории, куда файл будет скопирован при установке;
  2. Добавление файла в пакет инсталлятора;
  3. Указание инсталлятору установить файл.

После третьего шага должны получить:

  <Product ...>
    ...

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLLOCATION" Name="My Application">
        </Directory>
      </Directory>
    </Directory>

    <DirectoryRef Id="INSTALLLOCATION">
      <Component Id="MyApplicationFile" Guid="PUT-GUID-HERE">
        <File Id ="MyApplicationFile"
              Name="$(var.MyApplication.TargetFileName)"
              Source="$(var.MyApplication.TargetDir)\\$(var.MyApplication.TargetFileName)"
              DiskId="1"
              KeyPath="yes"
              Checksum="yes">
        </File>
      </Component>
      <Component Id="ReadMeFile" Guid="PUT-GUID-HERE">
        <File Id ="ReadMeFile"
              Name="ReadMe.txt"
              Source="$(var.MyApplication.TargetDir)\\ReadMe.txt"
              DiskId="1"
              KeyPath="yes" />
      </Component>
    </DirectoryRef>

    <Feature Id="ProductFeature" Title="My Application" Level="1">
      <ComponentRef Id="MyApplicationFile" />
      <ComponentRef Id="ReadMeFile" />
    </Feature>

    ...
  </Product>

Как проверить версию ОС

Для осуществления проверки версии ОС в Wix есть стандартное свойство VersionNT.

Пример:

  <Product ...>
    ...

    <!--Check OS version on the user's machine-->
    <Condition Message="This application is only supported on Windows XP, Windows Server 2003, Windows Vista, or higher.">
      <![CDATA[Installed OR (VersionNT >= 501)]]>
    </Condition>

    ...
  </Product>

Значения VersionNT можно найти на сайте http://msdn.microsoft.com набрав в поисковике Operating System Property Values.

Как проверить наличие .NET Framework требуемой версии

Процесс проверки состоит из следующих шагов:

  1. В WiX – проекте добавляете ссылку на WixNetFxExtension.dll;
  2. Добавляете namespace;
  3. Объявляете ссылку на свойство;
  4. Используете предопределенное свойство в проверке.

После второго шага должны получить:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" 
      xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">

После четвертого шага должны получить:

  <Product ...>
    ...

    <!--Check presence .NET Framework 3.5 on the user's machine-->
    <PropertyRef Id="NETFRAMEWORK35"/>

    <Condition Message="This application requires .NET Framework 3.5. Please install the .NET Framework then run this installer again.">
      <![CDATA[Installed OR NETFRAMEWORK35]]>
    </Condition>

    ...
  </Product>

Если необходимо проверить наличие другой версии, например 3.0, то вместо NETFRAMEWORK35 нужно писать NETFRAMEWORK30. Для остальных версий изменения аналогичны.

Как прочитать запись системного реестра

Иногда в процессе установки требуется проверить наличие файла определенной версии. Если вы точно знаете в какой директории лежит файл, то можете смело переходить к чтению следующего раздела. Если же директория точно неизвестна, то можно попробовать прочитать данную информацию из системного реестра.

Пример:

  <Product ...>
    ...

    <!--Check presence SomeProgram on the user's machine-->
    <Property Id="SOMEPROGRAMDIR">
      <RegistrySearch Id="SomeProgramDir"
                      Root="HKLM"
                      Key="Software\\Some Manufacturer\\Some Program"
                      Type="raw"/>
    </Property>

    ...
  </Product>

В системном реестре необходимая информация о директории может быть записана, например, в поле “значение по умолчанию” или InstallPath.

В данном примере, в RegistrySearch не было присвоено значения атрибуту Name, это означает, что чтение записи будет производиться по полю “значение по умолчанию”.

Как проверить версию файла

Чтобы проверить версию файла, атрибуту Path элемента DirectorySearch необходимо присвоить значение пути к файлу. Это значение может быть указано явно или через свойство. В предыдущем разделе информация о пути считывалась из системного реестра и присваивалась свойству c идентификатором SOMEPROGRAMDIR.

Пример:

  <Product ...>
    ...

    <Property Id="SOMEPROGRAMVERSION">
      <DirectorySearch Id="SomeProgramDirectory" Path="[SOMEPROGRAMDIR]">
        <FileSearch Name="SomeProgram.dll" MinVersion="1.2.3333.0"/>
      </DirectorySearch>
    </Property>

    <Condition Message="This application requires Some Program 1.2.3333.1. Please install the Some Program then run this installer again.">
      <![CDATA[SOMEPROGRAMVERSION]]>
    </Condition>

    ...
  </Product>

Обратите особое внимание на то, что значение минимальной версии (MinVersion) указывается на единицу меньше, чем требуется в действительности.

Как сделать запись в системный реестр

Допустим вы хотите записать в системный реестр информацию о директории, в которую будет установлена программа.

Пример:

  <Product ...>
    ...

    <DirectoryRef Id="TARGETDIR">
      <Component Id="RegistryEntries" Guid="PUT-GUID-HERE">
        <RegistryKey Root="HKLM"
                     Key="Software\\My Manufacturer\\My Application"
                     Action="createAndRemoveOnUninstall">
          <RegistryValue Type="string" Value="[INSTALLLOCATION]" KeyPath="yes"/>
        </RegistryKey>
      </Component>
    </DirectoryRef>

    ...
  </Product>

При этом Feature изменится следующим образом:

  <Product ...>
    ...

    <Feature Id="ProductFeature" Title="My Application" Level="1">
      <ComponentRef Id="MyApplicationFile" />
      <ComponentRef Id="ReadMeFile" />
      <ComponentRef Id="RegistryEntries" />
    </Feature>

    ...
  </Product>

Как добавить ярлык в меню Пуск

Процесс добавления ярлыка состоит из следующих шагов:

  1. Объявление директории, куда ярлык будет помещен при установке;
  2. Добавление ярлыка в пакет инсталлятора;
  3. Указание инсталлятору установить ярлык.

После первого шага должны получить:

  <Product ...>
    ...

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLLOCATION" Name="My Application">
        </Directory>
      </Directory>
      <Directory Id="ProgramMenuFolder">
        <Directory Id="ApplicationProgramsFolder" Name="My Application"/>
      </Directory>
    </Directory>

    ...
  </Product>

После второго шага должны получить:

  <Product ...>
    ...

    <DirectoryRef Id="ApplicationProgramsFolder">
      <Component Id="ApplicationShortcut" Guid="PUT-GUID-HERE">
        <Shortcut Id="ApplicationStartMenuShortcut"
                  Name="My Application"
                  Description="My Application Description"
                  Target="[INSTALLLOCATION]MyApplication.exe"
                  WorkingDirectory="INSTALLLOCATION"/>
        <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
        <RegistryValue Root="HKCU"
                       Key="Software\\My Manufacturer\\My Application"
                       Name="installed"
                       Type="integer"
                       Value="1"
                       KeyPath="yes"/>
      </Component>
    </DirectoryRef>

    ...
  </Product>

После третьего шага должны получить:

  <Product ...>
    ...

    <Feature Id="ProductFeature" Title="My Application" Level="1">
      <ComponentRef Id="MyApplicationFile" />
      <ComponentRef Id="ReadMeFile" />
      <ComponentRef Id="RegistryEntries" />
      <ComponentRef Id="ApplicationShortcut" />
    </Feature>

    ...
  </Product>

Как добавить ярлык удаления программы в меню Пуск

Для этого необходимо немного модифицировать добавление ярлыка в пакет инсталлятора (предыдущий раздел, шаг 2).

В результате должны получить:

  <Product ...>
    ...

    <DirectoryRef Id="ApplicationProgramsFolder">
      <Component Id="ApplicationShortcut" Guid="PUT-GUID-HERE">
        <Shortcut Id="ApplicationStartMenuShortcut"
                  Name="My Application"
                  Description="My Application Description"
                  Target="[INSTALLLOCATION]MyApplication.exe"
                  WorkingDirectory="INSTALLLOCATION"/>
        <Shortcut Id="UninstallProduct"
                  Name="Uninstall My Application"
                  Description="Uninstall My Application"
                  Target="[System64Folder]msiexec.exe"
                  Arguments="/x [ProductCode]"/>
        <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
        <RegistryValue Root="HKCU"
                       Key="Software\\My Manufacturer\\My Application"
                       Name="installed"
                       Type="integer"
                       Value="1"
                       KeyPath="yes"/>
      </Component>
    </DirectoryRef>

    ...
  </Product>

Как предоставить пользователю возможность запуска приложения по окончании установки

Процесс состоит из следующих шагов:

  1. В WiX – проекте добавляете ссылки на WixUIExtension.dll и WixUtilExtension.dll;
  2. Добавляете интерфейс пользователя в инсталлятор;
  3. Включаете действие пользователя;
  4. Инициируете действие пользователя.

После второго шага должны получить:

  <Product ...>
    ...

    <UI>
      <UIRef Id="WixUI_Minimal"/>
    </UI>

    <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch My Application"/>

    ...
  </Product>

После третьего шага должны получить:

  <Product ...>
    ...

    <Property Id="WixShellExecTarget" Value="[#MyApplicationFile]"/>
    <CustomAction Id="LaunchApplication"
                  BinaryKey="WixCA"
                  DllEntry="WixShellExec"
                  Impersonate="yes"/>

    ...
  </Product>

После четвертого шага должны получить:

  <Product ...>
    ...

    <UI>
      <UIRef Id="WixUI_Minimal"/>
      <Publish Dialog="ExitDialog"
               Control="Finish"
               Event="DoAction"
               Value="LaunchApplication">
        WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 AND NOT Installed
      </Publish>
    </UI>

    ...
  </Product>

Как использовать наборы диалогов

WiX предоставляет несколько встроенных наборов диалогов. В предыдущем разделе использовался набор “WixUI_Minimal”.

WixUI_Minimal – это простейший вариант набора диалогов. Его единственный диалог соединяет в себе диалог приветствия и диалог лицензионного соглашения и не включает диалога выбора компонентов установки.

WixUI_InstallDir – не предоставляет пользователю выбора компонентов установки, но добавляет диалог выбора директории, куда будет установлен продукт.

Для того, чтобы использовать именно этот набор, надо добавить свойство WIXUI_INSTALLDIR и немного изменить UI.

В результате должны получить:

  <Product ...>
    ...

    <Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION"/>

    <UI>
      <UIRef Id="WixUI_InstallDir"/>
      <Publish Dialog="ExitDialog"
               Control="Finish"
               Event="DoAction"
               Value="LaunchApplication">
        WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 AND NOT Installed
      </Publish>
    </UI>

    ...
  </Product>

Есть и другие встроенные наборы диалогов, подробнее о них можно прочитать в документации к Wix.

One thought on “Создаем свой первый инсталлятор на Windows Installer XML (WiX) v3.0 в Visual Studio.”

Leave a Reply

Your email address will not be published. Required fields are marked *