Ссылка на WixVariable, определенный в проекте библиотеки WiX из проекта установки WiX

Я пытаюсь настроить настройку и библиотеку 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>

после этого версию продукта можно установить as

  <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 ответов


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

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

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

так что вы можете использовать !(wix.BuildVersion) где-нибудь еще в вашем *.wxs, но вы не можете использовать его в качестве значения для Product/@Version. Насколько я знаю, единственная переменная binder, которую вы можете использовать здесь, -!(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 будет передано candle.exe, чтобы вы могли ссылаться на него с препроцессором переменная $(ВАР.BuildVersion). Это, конечно, не так чисто, как держать все это в *.wxs-файл, но это один из способов получить информацию о версии в свечу, чтобы ее можно было использовать в качестве переменной в Product/@Version. Я, конечно, хотел бы услышать лучшие способы сделать это.


у меня была аналогичная проблема при использовании тепла.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

возможно, полезно и в других местах.