понедельник, 23 августа 2010 г.

Setup-проекты в Visual C# Express

Одно из серьезных ограничений Visual C# Express - это невозможность использования майкрософтовских Setup-проектов. Впрочем, эти проекты далеко не идеальны, и как показала практика, куда эффективнее использовать для создания вашего msi бесплатный продукт Windows Installer XML (WIX).


В этой статье я расскажу, как интегрировать WIX в Visual C# Express и научиться создавать с его помощью полномасштабные msi-инсталляторы.


Что такое WIX?


Основная фишка WIX - это представление msi-файла в xml-виде. WIX Toolset содержит несколько консольных утилит для преобразований wxs <=> msi (wxs - это расширение WIX-файлов). XML легко сериализовать - а значит нет проблем в создании визуального редактора, и такие редакторы уже есть. Близость xml-представления к своему msi-прообразу тоже дает несколько плюсов:
  • неограниченная ничем возможность кастомизации создаваемых инсталляторов;
  • изучая WIX, вы изучаете формат MSI;
  • ну и наконец, любой msi может быть декомпилирован в WIX!
Хотите создать инсталлятор, аналогичный генерируемому Setup-проектом платных версий студии? Нет ничего проще! Раскопайте где-нибудь уже скомпилированный msi, и сконвертируйте его в wxs с помощью утилиты dark, входящей в состав WIX Toolset. Но лучше, возьмите за основу более интересный инсталлятор :)

Интеграция в Visual Studio

WIX интегрируется в студию с помощью специального плагина Votive. Но в Visual Studio Express плагины не работают. Приходится довольствоваться неполной интеграцией. Давайте посмотрим, что можно сделать в этом направлении, не нарушая лицензионное соглашение на этот замечательный продукт.

Во-первых, установите WIX в систему. Если у вас Visual C# 2010 Express, скачайте версию WIX не ниже 3.5 (на текущий момент stable версия - 3.0, но она умеет работать только с Visual C# 2008 Express). Установив пакет в систему, вы получите intellisense для wxs-файлов.

Intellisense для WXS-файлов в Visual C# Express
Замечу, Intellisense классный. Очень подробные комментарии по каждому свойству. Огромный респект создателям!

Кроме того, WIX установит все требуемые для его работы файлы, в том числе, к примеру, файл wix.targets, необходимый для интеграции с MSBuild. С этих пор, можно создавать файлы проектов вручную. Вы сможете добавлять такие проекты в ваш Solution, и использовать, как обычный проект Visual Studio (т.е. жмем на этом проекте Build => получаем msi).

Листинг SetupProject.csproj:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> 
  3.  <PropertyGroup> 
  4.     <ProductVersion>3.0</ProductVersion> 
  5.     <ProjectGuid>69F99A15-3E62-4273-9DEA-E102A2D2C130</ProjectGuid> 
  6.     <SchemaVersion>2.0</SchemaVersion> 
  7.     <OutputName>SetupProject</OutputName> 
  8.     <OutputType>Package</OutputType> 
  9.     <OutputPath>.\</OutputPath> 
 10.     <WixVersion>3.x</WixVersion> 
 11.     <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v$(WixVersion)\Wix.targets</WixTargetsPath> 
 12.     <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v$(WixVersion)\Wix.targets</WixTargetsPath> 
 13.     <UseVSHostingProcess>false</UseVSHostingProcess> 
 14.  </PropertyGroup> 
 15.  <ItemGroup> 
 16.     <Compile Include="SetupProject.wxs" /> 
 17.  </ItemGroup> 
 18.  <Import Project="$(WixTargetsPath)" /> 
 19. </Project>

Шаблон проекта

Но ведь вручную, всё-таки, неинтересно! Почему бы не добавить наш собственный Project Template? Берем online-документацию по созданию VSTemplate, и... получаем файлик SetupProject.vstemplate:
Как видно, vstemplate использует файлы SetupProject.csproj, SetupProject.wxs, и SetupProject.ico. Рассмотрим их по порядку:

  1. <VSTemplate Version="2.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005"> 
  2.  <TemplateData> 
  3.     <Name _locID="TSDATA_DUT_Name">Setup Project</Name> 
  4.     <Description _locID="TSDATA_DUT_Description">WIX-based setup project</Description> 
  5.     <Icon>SetupProject.ico</Icon> 
  6.     <ProjectType>CSharp</ProjectType> 
  7.     <CreateNewFolder>true</CreateNewFolder> 
  8.     <DefaultName>SetupProject</DefaultName> 
  9.     <ProvideDefaultName>true</ProvideDefaultName> 
 10.     <PromptForSaveOnCreation>false</PromptForSaveOnCreation> 
 11.  </TemplateData> 
 12.  <TemplateContent> 
 13.     <Project File="SetupProject.csproj" TargetFileName="$safeprojectname$.csproj" ReplaceParameters="true"> 
 14.      <ProjectItem ReplaceParameters="true" OpenInEditor="true" TargetFileName="$safeprojectname$.wxs">SetupProject.wxs</ProjectItem> 
 15.     </Project> 
 16.  </TemplateContent> 
 17. </VSTemplate>

Csproj-файл у нас уже есть, но его нужно немножко подредактировать. Мы ведь не хотим, чтобы проекты создавались с одинаковыми Guid'ами? Кроме того, нужно учесть также возможность смены имени проекта. В общем, в csproj-файле следует заменить "69F99A15-3E62-4273-9DEA-E102A2D2C130" на "$guid1$", а "SetupProject" на "$safeprojectname$".

WXS-файл - это файл-пример. В простейшем случае он может включать только базовый xml, например так:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  3.   <Product Id="$guid2$" Name="$safeprojectname$" Language="1033" Version="1.0.0.0" Manufacturer="$safeprojectname$" UpgradeCode="$guid3$">
  4.     <Package InstallerVersion="200" Compressed="yes" />
  5.     <Media Id="1" Cabinet="SetupProject.cab" EmbedCab="yes" />
  6. 
  7.     <Directory Id="TARGETDIR" Name="SourceDir">
  8.       <Directory Id="ProgramFilesFolder">
  9.         <Directory Id="INSTALLDIR" Name="$safeprojectname$">
 10.           <!-- add components here -->
 11.         </Directory>
 12.       </Directory>
 13.     </Directory>
 14. 
 15.     <Feature Id="ProductFeature" Title="$safeprojectname$" Level="1">
 16.       <!-- add component refs here -->
 17.     </Feature>
 18.   </Product>
 19. </Wix>

В более сложном случае, советую включить в этот файл готовый шаблон вашего любимого установщика.

Да, и иконку для проекта (32х32) можно спокойно найти, например, на IconFinder'е.

Теперь берем все созданные нами файлы - vstemplate, csproj, wxs и ico, и запаковываем в обычный zip-архив (можете скачать готовый тут). Поздравляю, мы только что создали простенький шаблон проекта.

Добавление шаблона в VS

Добавление шаблона реализуется стандартными средствами Visual Studio:


  1. Копируем SetupProject.zip в каталог C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\VCSExpress\ProjectTemplates\1033\
  2. Запускаем студию (Common7\IDE\vcsexpress.exe) с ключом /installvstemplates. При этом шаблоны устанавливаются, правда сама студия не запускается.
  3. Чтобы сбросить кэш, запускаем vcsexpress.exe с ключом /clearsettings, получаем окошко, сообщающее о подготовке к студии к первому запуску... и наконец, она запустилась!


  4. File -> New Project... -> Setup Project


  5. Тыкаем создать, получаем готовый к использованию проект.



Вуаля!

P.S. Очень хорошо, с грамотными примерами, про создание WXS написано в серии статей Дмитрия Рыжкова на хабре.

2 комментария:

  1. Спасибо все работает, только ключ не /clearsettings а /ResetSettings

    ОтветитьУдалить
  2. Здравствуйте! Помогите, пожалуйста, разобраться с контролами типа Edit (Control Id="myEdit1" Type="Edit" Property="REMOTE_PORT" Height="17" Width="150" X="56" Y="58" Sunken="yes">). Нигде не могу найти описание, как считать то, что ввел пользователь в это поле (например Порт) и как потом это значение использовать при установке вместо значения по умолчанию, которое прописано в конфиге.

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

Внимание! Реклама и прочий спам будут беспощадно удаляться.