четверг, 17 января 2013 г.

WIX + NET 4.0 Framework + Microsoft Windows Installer 3.1

Очень часто, перед установкой программы, требуется проверить наличие нужных в системе компонентов. В данной статье я покажу как в WIX проверить наличие установленного NET Framework 4.0 и Microsoft Windows Installer 3.1.
Для начала создадим новый проект Windows Installer XML с говорящим названием - Setup. Добавим в наш проект файл Variables.wxi, в котором будут содержаться переменные, описывающие параметры нашего приложения:

Variables.wxi:
<?xml version="1.0" encoding="utf-8"?>
<Include>
  <?define ProductName="WPFCSHARP Program"?>
  <?define ProductVersion="1.0.0.0" ?>
  <?define ProductCode="A5C649E2-7180-401C-A188-B23A4E766432"?>
  <?define UpgradeCode="90BCED71-26CD-483E-AE93-0DB3510B7313"?>
  <?define Manufacturer="WPFCSHARP"?>
</Include>
Обратите внимание, что уникальные идентификаторы в вашем приложении должы быть другими. Для генерации GUID'ов в VIsual Studio используйте утилиту, которая находится в меню Сервис >> Создать GUID.

Затем изменим главный файл в проекте Product.wxs следующим образом:

Product.wxs :
  <?include Variables.wxi?>

  <Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1049" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">

Здесь мы просто подключили файл с переменными и установили их в качестве описания продукта. Замечу, что значение  Language я установил в 1049, что соответствует русскому языку. Однако для того, чтобы наш установщик поддерживал русский язык - этого не додстаточно. Культуру так же нужно прописать в свойствах проекта: на вкладке "Build" параметр "Culturs to build" установить значение ru-RU (или перечислить несколько культур через точку с запятой если проект будет поддерживать несколько языков). И последний штрих для локализации проекта - добавить файл локализации WixUI_ru-ru.wxl, в котором будут описываться локализованные ресурсы:

WixUI_ru-ru.wxl :
<?xml version="1.0" encoding="utf-8"?>
<WixLocalization Culture="ru-ru" xmlns="http://schemas.microsoft.com/wix/2006/localization">
 <String Id="YOURLOCID">Your localized string</String>
</WixLocalization>
Если проект поддерживает несколько языков, то файл локализации нужно создать для каждой культуры.

Теперь перейдем к основной части.
1. Добавим в проект ссылки на вспомогательные сборки (по умолчанию эти сборки находятся в папке "C:\Program Files (x86)\Windows Installer XML v3.5\bin\"):
  • WixNetFxExtension.dll (включает набор дополнительных пользовательских действий)
  • WixUIExtension.dll (содержит стандартный набор диалогов)
2. Отредактируем файл проекта Setup.wixproj, добавив в него новый тег ItemGroup:

Code:
<ItemGroup>
    <BootstrapperFile Include=".NETFramework,Version=v4.0">
      <ProductName>.NET Framework 4.0 Full</ProductName>
    </BootstrapperFile>
    <BootstrapperFile Include="Microsoft.Windows.Installer.3.1">
      <ProductName>Windows Installer 3.1</ProductName>
    </BootstrapperFile>
  </ItemGroup>

и раскомментируем задачу AfterBuild и сохраним его в следующем виде:

Code:
  <Target Name="AfterBuild">
    <GenerateBootstrapper ApplicationFile="$(TargetFileName)" ApplicationName="WPFCSHARP Program" BootstrapperItems="@(BootstrapperFile)" ComponentsLocation="Relative" CopyComponents="True" OutputPath="$(OutputPath)" Path="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\" />
  </Target>
Для того, чтобы изменить файл проекта, следует выгрузить проект из решения (в контекстном меню проекта пункт меню "Отменить загрузку проекта"), затем в этом же меню выбрать пункт "Изменить Setup.wixproj " и после редактирования выбрать "Перезагрузить проект".

В этом коде мы по сути указываем где установщику брать дополнительные пакеты. Соответственно они должны находится в указанной папке "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages", иначе при компиляции проекта появится ошибка (обратите внимание на разрадность операционной системы).
Если вам требуется установить другую версию NET. Framework или же другой продукт, то вам следует парвильно указать параметр Include тега  BootstrapperFile. Где его взять? А найти его можно в XML-описании каждого продукта, которое хранится в папке продукта. К примеру для NET 4.0 Framework это файл: "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\DotNetFX40\Product.xml". В этом файле в корневом теге Product есть аттрибут ProductCode, в котором и указан код продукта. Так для  NET 4.0 Framework Client Profile код продукта - ".NETFramework,Version=v4.0,Profile=Client", для Sql Express 2008 - "Microsoft.Sql.Server.Express.10.0" и т.д.
После всех манипуляций структура проекта и скомпилированный вариант должны выглядеть так, как показано на рисунке:


Все что нам осталось сделать - это вставить проверку наличия в системе нужного компонента. Для этого в файл  Product.wxs добавим следующие строки:

Product.wxs :
    <PropertyRef Id="NETFRAMEWORK40FULL"/>
    <Condition Message='This setup requires the .NET Framework 4.0.'>
      <![CDATA[Installed OR NETFRAMEWORK40FULL]]>
    </Condition>

После чего соберем весь проект и попробуем установить наше приложение. Так как у меня под рукой совершенно случайно оказалась подготовленная виртуалка с "пустым" Windows XP (для пущей уверенности) при попытке установить приложение открылось окно с предложением для начала установить  NET 4.0 Framework.


Теперь установка приложения продолжится только после установки требуемых компонентов.

5 комментариев:

  1. В результате на выходе будет один файл Setup с включенными в него Framework'-ми или набор файлов?

    ОтветитьУдалить
  2. Будет набор файлов. На рисунке выше есть скриншот структуры папок после компиляции.

    ОтветитьУдалить
  3. Добрый день Кирилл!
    Спасибо за статью, для начинающего - самое то!
    Только есть маленькая неувязка ...
    Я скачал Ваш проект полностью, скомпилировал и попытался его запустить через setup...
    Получил ошибку -
    "Не удается найти файл "Setup.msi" приложения.

    Дополнительные сведения см. в журнале установки, находящемся в "C:\Users\VIKTOR~1.MIG\AppData\Local\Temp\VSD438.tmp\install.log"."

    Если файлы вынести из ru-Ru наверх к setup - то все работает
    Как устранить эту ошибку?

    ОтветитьУдалить
  4. Виктор, спасибо за комментарий.
    Чтобы обойти эту проблему, можно сделать так, чтобы все файлы установки копировались, к примеру, в папку ru-RU следующим образом:
    Для компонента GenerateBootstrapper (в файле проекта) указать OutputPath="$(OutputPath)\ru-RU".

    ОтветитьУдалить