Я часто это слышу и не думаю, что документация по 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.Я, конечно, хотел бы услышать о лучших способах сделать это.