Я часто слышу об этом, и я не думаю, что документация 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. Это проблема, потому что Candle.exe применяет проверку к определенным полям, таким как Product/@Version. Он понятия не имеет, что будет оцениваться !(wix.BuildVersion)
, поэтому он не может проверить, что он даст действительную версию. В отличие от этого, вы можете обойтись без !(bind.FileVersion.FileId)
, потому что во время компиляции Candle убеждается, что во время компоновки она будет разрешена в допустимую версию (FileId — это прямая ссылка на файл в продукте, поэтому Candle верит, что он будет существовать, чтобы получить версию номер по ссылке).
Таким образом, вы можете использовать !(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, но это один из способов получить информацию о версии в Candle, чтобы ее можно было использовать в качестве переменной в Product/@Version. Я, конечно, хотел бы услышать о лучших способах сделать это.
person
Anon
schedule
19.12.2011