Чувам това много често и не мисля, че документацията на 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