Подтвердить что ты не робот

Ссылка на 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>

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

  <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 (или некоторый вывод этого) доступным из настройки?

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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