Как установить версию установщика WiX на текущую версию сборки?

134

Я написал приложение и его установщик WiX и поставил его под контроль версий с помощью Subversion. Когда сборщик установщика WiX собирается, я хочу, чтобы его номер версии был текущей версией сборки приложения. Как мне это сделать? Я использовал c # для кодирования приложения.

NB Я использую ccnet для создания этого проекта

Дракон
источник

Ответы:

181

Вы можете использовать Product/@Version="!(bind.FileVersion.FileId)"(замените FileIdна Idфайл, из которого вы хотите получить номер версии), и light.exe заполнит значение версией файла, на который ссылается FileId.

Роб Меншинг
источник
4
Как раз то, что я искал! Хотя мне пришлось использовать «! (Bind.FileVersion.FileId)» («!» Вместо «$»), в противном случае я получил ошибку директивы препроцессора.
Николай Пясецкий
8
Да, извините, постоянная умственная ошибка, которую я совершаю. $ является переменной препроцессора и! является переменной связующего.
Роб Меншинг
20
Обратите внимание, что «Fileid» должен быть значением из элемента <File Id = «Fileid» ...> и, очевидно, может содержать символ точки (.).
Джеймс Хьюгард
6
Возможно ли сделать это и для связки / загрузчика?
noelicus
6
Ссылка на соответствующую документацию, раздел: Переменные Binder
McDon
39

Я сделал это в одном из моих проектов, написав расширение препроцессора для чтения версии файла из моего исполняемого файла. Итак, файл WiX выглядит примерно так:

<?define ProductName="$(fileVersion.ProductName($(var.MyApp.TargetPath)))" ?>
<?define CompanyName="$(fileVersion.CompanyName($(var.MyApp.TargetPath)))" ?>
<?define ProductVersion="$(fileVersion.ProductVersion($(var.MyApp.TargetPath)))" ?>
<Product 
    Id="<product ID>" 
    Name="$(var.ProductName)" 
    Version="$(var.ProductVersion)" 
    Manufacturer="$(var.CompanyName)" 
    Language="1033" 
    UpgradeCode="<upgrade code>">

Я разместил код для в CodePlex: http://wixfileversionext.codeplex.com/

Крис Кацор
источник
Ваше расширение все еще работает? Я попытался добавить его в качестве ссылки, и я получил ошибку.
Стефан Васильевич
Это расширение прекрасно работает с Wix 3.5, после обновления до Wix 3.9 оно выдает исключение NullPointerException. Очевидно, что-то сломалось между этими версиями.
Джиго
2
@Gigo Я получил его через <?define ProductName="!(bind.property.ProductName)" ?><?define CompanyName="!(bind.property.Manufacturer)" ?><?define ProductVersion=!(bind.FileVersion.FileId) ?> Где FileIdзначение Idатрибута одного из ваших Fileэлементов внутри a Component.
Джаред
Ссылка на CodePlex не открывается для меня. Есть ли другой способ, кроме написания собственного расширения препроцессора?
RDV
28

В случае, если кто-то ищет реальный пример XML, это работает со сборками .NET (и вам не нужно делать атрибуты Assembly или KeyPath). Я удалил несвязанный код с [...] заполнителями:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product [...] Version="!(bind.fileVersion.MyDLL)">
        [...]
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder" Name="PFiles">
                <Directory Id="INSTALLDIR" Name="MyDLLInstallLocation">
                    <Component Id="MainLib" Guid="[...]">
                        <File Id="MyDLL" Name="MyDll.dll" Source="MyDll.dll" />
                        [...]
                    </Component>
                    [...]
                </Directory>
            </Directory>
        </Directory>
    </Product>
</Wix>
K0D4
источник
1
Это гораздо лучший ответ. Спасибо за рабочий пример.
катится
где он выбирает фактический номер версии?
Foobar
@foobar Это было давно, так как я был здесь, но если вы посмотрите на строку, !(bind.fileVersion.MyDLL)она использует 3-ю часть в отношении <File Id="MyDLL"...раздела
K0D4
Это хорошо сработало для меня. Работает как для скомпилированных исполняемых файлов, так и для dll, что отлично подходит для закрепления версии установщика и содержимого пользовательского интерфейса в информации о сборке exe, без необходимости что-либо менять в нескольких местах
rcbevans
21

Вот очень простой способ получить версию Bootstrapper Bundle, соответствующую MyApp AssemblyVersion, используя BeforeBuild Targetи DefineConstants.

Bundle.wxs:

<Bundle Name="$(var.ProductName) Bootstrapper v$(var.BuildVersion)"
     Version="$(var.BuildVersion)"

Bootstrapper.wixproj:

<Target Name="BeforeBuild">
  <GetAssemblyIdentity AssemblyFiles="..\MyApp\bin\$(Configuration)\MyApp.exe">
    <Output TaskParameter="Assemblies" ItemName="AssemblyVersion" />
  </GetAssemblyIdentity>
  <PropertyGroup>
    <DefineConstants>BuildVersion=%(AssemblyVersion.Version)</DefineConstants>
  </PropertyGroup>
</Target>
Брок Хенсли
источник
@AliKazmi Вы определили свой var.ProductNameи var.BuildVersionгде-то выше своего <Bundle>?
Брок Хенсли
2
Я попробовал это и не могу рекомендовать этого достаточно - объедините это с патчером сборки для TeamCity, и вы получите формулу победы. Я использовал не элемент Bundle, а элемент product, и все еще работал на меня.
ИбрарМумтаз
VS просто любит игнорировать BeforeBuildцель, поэтому может потребоваться указать явно, AfterTargets="AfterResolveReferences"если вы создаете в IDE
Дмитрий
Я добавил код Bootstrapper.wixproj в свой * .wixproj и в файле Product.wxs, я определил переменную buildversion как:
RDV
4

Вы можете передать версию скрипту MSBuild для вашего проекта установки так же, как вы можете передать скрипт сборки приложения.

Например, если ваша система CI определяет переменные AppVersionи BuildNumberи передает их в ваши скрипты MSBuild, ваш wixproj может создать соответствующее Versionсвойство, которое он передает в Wix следующим образом:

<PropertyGroup>
    <Version Condition=" '$(BuildNumber)' == '' ">0.0.1</Version>
    <Version Condition=" '$(BuildNumber)' != '' ">$(AppVersion).$(BuildNumber)</Version>
    <DefineConstants>Version=$(Version)</DefineConstants>
</PropertyGroup>

Первое определение Versionпредоставляет значение по умолчанию, когда вы строите локально. Чем бы это ни закончилось, оно становится Versionпеременной в Wix. Используйте его в файле wsx следующим образом:

<Product Version="$(var.Version)" ...>
    <Package Description="$(var.ProductName) $(var.Version): $(var.ProductDescription)" ... />

Мне нравится включать версию в описание, чтобы ее можно было легко найти в проводнике (как столбец в подробном представлении или на странице свойств) независимо от имени файла.

Передача версии в качестве переменной дает вам больше контроля, чем чтение ее из файла. Когда вы читаете из файла, вы получаете все 4 части программной версии. Однако ProductVersion предназначен только для использования первых 3 частей.

Эдвард Брей
источник
Спасибо, это спасло мой день. Кстати: верхний отрыванный код входит в ваш проект (* .wxiproj). Управлять Devops / VSTS CI-Build - это лучший ответ. Поскольку у меня уже есть готовая переменная окончательной версии. В моем случае это оказалось так: <Version Condition=" '$(BuildVersionOfAsm)' != '' ">$(BuildVersionOfAsm)</Version>тогда как BuildVersionOfAsm является переменной в конвейерах devops.
Робетто
Я хочу выбрать версию динамически, этот метод потребует, чтобы я продолжал обновлять версию в * .wixproj. Есть ли способ к любой версии DLL в этой области?
RDV
@RDV Целью этого подхода не является изменение каких-либо файлов в системе контроля версий, включая .wixproj. Динамический номер версии предоставляется вашей системой CI (AppVersion и BuildNumber в этом примере). Как правило, вы устанавливаете основной и вспомогательный номера версий в качестве переменных CI и позволяете системе CI динамически генерировать номер сборки.
Эдвард Брей
Отлично - именно то решение, которое мне было нужно, в том числе по умолчанию для локальных сборок.
полковник