Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically increment and synchronize version for product and bootstrapper

I'm trying to implement automatic versioning so that when I build my Bootstrapper, both the MyApp and Bootstrapper versions are automatically incremented and synchronized. Otherwise you end up with duplicate bootstrap entries in the add/remove programs for each installation attempt with matching versions.

When I build the bootstrapper, an AfterBuild target uses GetAssemblyIdentity to get the automatically generated version of MyApp successfully, and the bootstrapper output file is properly named with the incremented version number e.g. MyApp.1.0.5123.1352.exe

But, when I install this Bootstrapper, the version that shows in add/remove programs is always 1.0.0.0.

I've tried using bindings in the Bootstrapper Bundle Version field but I can't get it to read the MyApp version.

Using !(bind.packageVersion.MyApp) results in never incrementing 1.0.0.0.
Using !(bind.assemblyName.MyApp) results in build errors (Unresolved bind-time variable).
Using !(bind.FileVersion.filAAF013CA9B89B07C81031AE69884BF11) results in build errors (Unresolved bind-time variable). <-- Makes sense as the FileID exists in the Setup project, and this is the Bootstrapper project.

What can I do to get my Bootstrapper Bundle to have the same version as the MyApp it is packaging?

=====MyApp\AssemblyInfo.cs=====

[assembly: AssemblyVersion("1.0.*")] 
[assembly: AssemblyFileVersion("1.0.*")] 

=====Setup.wixproj=====

<Target Name="BeforeBuild">
  <PropertyGroup>
    <LinkerBaseInputPaths>..\MyApp\bin\$(Configuration)\</LinkerBaseInputPaths>
  </PropertyGroup>
  <HeatDirectory OutputFile="MyApp_Files.wxs" Directory="..\MyApp\bin\$(Configuration)\" DirectoryRefId="INSTALLLOCATION" ComponentGroupName="MyApp_Project" SuppressCom="true" SuppressFragments="true" SuppressRegistry="true" SuppressRootDirectory="true" AutoGenerateGuids="false" GenerateGuidsNow="true" ToolPath="$(WixToolPath)" Condition="'%(ProjectReference.PackageThisProject)'=='True'" />
</Target>

=====Bootstrapper.wixproj=====

<Target Name="AfterBuild">
    <GetAssemblyIdentity AssemblyFiles="..\MyApp\bin\$(Configuration)\MyApp.exe">
        <Output TaskParameter="Assemblies" ItemName="AssemblyVersion" />
    </GetAssemblyIdentity>
    <Copy SourceFiles=".\bin\$(Configuration)\$(OutputName).exe" DestinationFiles=".\bin\$(Configuration)\MyApp.%(AssemblyVersion.Version).exe" />
    <Delete Files=".\bin\$(Configuration)\$(OutputName).exe" />
</Target>

=====Bootstrapper\Bundle.wxs=====

<Bundle Name="$(var.ProductName) Bootstrapper v!(bind.packageVersion.MyApp)" 
        Version="!(bind.packageVersion.MyApp)"
like image 801
Brock Hensley Avatar asked Sep 25 '13 20:09

Brock Hensley


2 Answers

This is what I would do:

  1. In my assembly I use auto versioning: AssemblyVersion("1.0.*")

  2. In the setup project reference the version using binding to the assembly: !(bind.fileVersion.MyAssembly.dll) (MyAssembly.dll is the File/@Id of the assembly)

  3. In the bundle using binding to the setup version: !(bind.packageVersion.Setup) (Setup is the project name as is referenced in the bundle project.)
like image 114
Neil Avatar answered Oct 12 '22 02:10

Neil


Got it!!! I didn't realize you can declare Variables aka DefineConstants in a BeforeBuild Target.

Below is an example BeforeBuild Target that generates a variable BuildVersion

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>
  <!-- This is extra, not needed: Renames output file with version number -->
  <Target Name="AfterBuild">
    <GetAssemblyIdentity AssemblyFiles="..\MyApp\bin\$(Configuration)\MyApp.exe">
      <Output TaskParameter="Assemblies" ItemName="AssemblyVersion" />
    </GetAssemblyIdentity>
    <Copy SourceFiles=".\bin\$(Configuration)\$(OutputName).exe" DestinationFiles=".\bin\$(Configuration)\MyApp.%(AssemblyVersion.Version).exe" />
    <Delete Files=".\bin\$(Configuration)\$(OutputName).exe" />
  </Target>
like image 25
Brock Hensley Avatar answered Oct 12 '22 02:10

Brock Hensley