Ссылка на переменную Wix, определенную в проекте библиотеки WiX, из проекта установки WiX - PullRequest
23 голосов
/ 06 декабря 2011

Я пытаюсь настроить установку и библиотеку WiX так, чтобы версия одного из файлов в библиотеке использовалась в качестве версии продукта / @ в настройке.

Фон

В конфигурации с файлами, определенными локально, это относительно просто, если предположить, что на проект компонента ссылается проект WiX, а затем настроить:

  <Component Id="Company.Assembly" Guid="[GUID]">
    <File Id="Company.AssemblyFile"
          Name="Company.Assembly.dll" KeyPath="yes"
          DiskId="1"
          Source="$(var.Company.Assembly.TargetPath)" />
  </Component>

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

  <Product Id="[GUID]"
           Name="Product Name"
           Language="1033"
           Version="!(bind.FileVersion.$(var.Company.AssemblyFile
                    .TargetFileName))"
           Manufacturer="Company Name"
           UpgradeCode="[GUID]">

Выпуск

Таким образом, переместив все компоненты в проект библиотеки WiX, больше невозможно напрямую ссылаться на переменную !(bind.FileVersion.$(var.Company.AssemblyFile.TargetFileName)).

Я пытался настроить WixVariable в библиотеке

WixVariable Id="BuildVersion" Value="!(bind.FileVersion.Company.AssemblyFile)"/>

А потом ссылаться на это из настройки

  <Product Id="[GUID]"
           Name="Product Name"
           Language="1033"
           Version="!(wix.BuildVersion)"
           Manufacturer="Company Name"
           UpgradeCode="[GUID]">

Без успеха.

Требуется ли какой-либо дополнительный шаг или синтаксис в библиотеке или настройке, чтобы сделать WixVariable (или его производную) доступным из установки?

Ответы [ 2 ]

49 голосов
/ 19 декабря 2011

Я часто это слышу и не думаю, что документация по WiX особенно хорошо объясняет ситуацию, так что вот она.Короткий ответ: ваш синтаксис правильный;На переменную, объявленную с элементом WixVariable, ссылается синтаксис !(wix.VariableName), и вы можете использовать переменные, которые были определены в указанной библиотеке, поэтому !(wix.BuildVersion) правильно для приведенного выше примера.Причина, по которой это не работает, заключается в том, что значение нужно проверять на этапе компиляции, но оно не генерируется до фазы компоновки.Итак, вот длинный ответ:

Существует два различных типа переменных, на которые вы можете ссылаться в файле * .wxs; препроцессор переменные и связующее (или компоновщик ) переменные.На первый ссылается синтаксис $, например $(var.VariableName), а на второй -!синтаксис, например !(bind.FileVersion.FileId).Основное различие простое: переменные препроцессора анализируются на этапе компиляции (с помощью Candle.exe), а переменные связующего анализируются на этапе компоновки (с помощью light.exe).Компилятор отвечает за получение исходных файлов * .wxs и их компиляцию в файлы * .wixobj;он не обрабатывает фактическую полезную нагрузку, поэтому не может прочитать информацию о версии из связанного файла.Файлы * .wixobj затем передаются компоновщику, который обрабатывает полезную нагрузку и создает базу данных MSI.Компоновщик отвечает за сбор метаданных из полезной нагрузки, поэтому он может предоставлять значения для таких переменных, как !(bind.FileVersion.FileId).

Обратите внимание, что переменная, объявленная с элементом WixVariable, указывается с помощью!синтаксис, так что это переменная связующего;он будет доступен для light.exe, но не будет доступен для СВ.Это проблема, потому что Candle.exe применяет проверку к определенным полям, таким как Product / @ Version.Он не знает, что !(wix.BuildVersion) будет оценивать, поэтому он не может проверить, что он даст правильную версию.Напротив, вы можете избежать неприятностей с !(bind.FileVersion.FileId), потому что свеча удовлетворена во время компиляции, что она преобразуется в допустимую версию во время ссылки (FileId является прямой ссылкой на файл в продукте, поэтому свеча верит, что он будет существовать, чтобы привести кномер версии по ссылке).

Таким образом, вы можете использовать !(wix.BuildVersion) в любом месте вашего * .wxs, но вы не можете использовать его в качестве значения для Product / @ Version.Насколько я знаю, единственная переменная связующего, которую вы можете использовать здесь, это !(bind.FileVersion.FileId), но, очевидно, это не очень хорошо, если вы хотите получить значение из библиотеки, на которую ссылаются.В противном случае вам просто нужно будет получить информацию о версии из другого места и передать ее в WiX, чтобы она была доступна во время компиляции.Если вы используете MSBuild, он может запрашивать информацию о версии с помощью задачи GetAssemblyIdentity и передавать ее в WiX через свойство DefineConstants.Следующие цели в вашем файле * .wixproj должны это делать:

<Target Name="BeforeBuild">
  <GetAssemblyIdentity AssemblyFiles="[Path.To.Target.File]">
    <Output TaskParameter="Assemblies" ItemName="AsmInfo" />
  </GetAssemblyIdentity>
  <CreateProperty Value="%(AsmInfo.Version)">
    <Output TaskParameter="Value" PropertyName="BuildVersion" />
  </CreateProperty>
  <CreateProperty Value="$(DefineConstants)">
    <Output TaskParameter="Value" PropertyName="DefineConstantsOriginal" />
  </CreateProperty>
  <CreateProperty Value="$(DefineConstants);BuildVersion=$(BuildVersion)">
    <Output TaskParameter="Value" PropertyName="DefineConstants" />
  </CreateProperty>
</Target>
<Target Name="AfterBuild">
  <CreateProperty Value="$(DefineConstantsOriginal)">
    <Output TaskParameter="Value" PropertyName="DefineConstants" />
  </CreateProperty>
</Target>

Свойство BuildVersion будет передано свече, поэтому вы можете ссылаться на него с помощью переменной препроцессора $ (var.BuildVersion).Это, конечно, не так чисто, как хранить все это в файле * .wxs, но это один из способов получить информацию о версии в свечу, чтобы ее можно было использовать в качестве переменной в Product / @ Version.Я, конечно, хотел бы услышать о лучших способах сделать это.

1 голос
/ 28 мая 2013

У меня была похожая проблема при использовании Heat.exe, это позволило мне переопределить исходную переменную, не связываясь с системными переменными среды или другими подобными:

"%wix%bin\heat.exe" dir "$(SolutionDir)Web\obj\$(Configuration)\Package" -cg PACKAGEFILES -gg -g1 -sreg -srd -dr DEPLOYFOLDER -var wix.PackageSource="$(SolutionDir)Web\obj\$(Configuration)\Package" -out "$(SolutionDir)WebInstaller\PackageFragment.wxs"

Я думаю этоСинтаксис может использоваться для любого объявления переменной, которое иначе не будет работать во время компоновки:

<wix.YOURVAR="VALUE">-in command line/<!(wix.YOURVAR="VALUE")>-in .WXS files

Может быть полезно и в других местах.

...