Automatically increment and synchronize version for product and bootstrapper
Asked Answered
I

2

8

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)"
Iliac answered 25/9, 2013 at 20:51 Comment(1)
bind.packageVersion can only read the version from a setup project so I would expect that to be bind.packageVersion.Setup.Ignition
I
8

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>
Iliac answered 25/9, 2013 at 21:51 Comment(5)
Hmmm... when I try this I get "Undefined preprocessor variable '$(var.BuildVersion)'." I'm trying to grab version, company name, product name, etc from the Assembly. (I'm just using your "BeforeBuild" section and replacying MyApp with my app path/name)Edgeways
Make sure the path to the exe or dll is correct, it is relative to where your Bootstrapper project lies, this is working for me I'm not sure why you would get that error if it is able to find the fileIliac
Thanks dirt, I managed to get the buildversion to work. I was trying to extend your technique and also grab Company, Product, etc from the Assembly metadata, but wasn't able to get that to work.Edgeways
I'm having some difficulty with this. I am packaging an msi instead of an exe; therefore, I have another wix project for that the msi. I tried copying the BeforeBuild tasks (i excluded the afterbuild portion), but couldn't get it to work. Being uncertain if wix setup projects supported define constants. I tried an alternate route. I have tried <CreateProperty Value="%(AssemblyVersion.Version)"> <Output TaskParameter="Value" PropertyName="BuildVersion" /> </CreateProperty> but the property is never set. Any advice is appreciated.Seafood
This did not work for me. I set message tasks showing that the property for BuildVersion was set; however, the property lost scope and a resulted in error: 'Undefined preprocessor variable '$(var.BuildVersion' Note that I am using a setup project and not a bootstrapper project.Seafood
I
21

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.)
Ignition answered 26/9, 2013 at 13:1 Comment(8)
I set Setup\Product.wxs Version to !(bind.fileVersion.MyFileID) and Bootstrapper\Bundle.wxs Version to !(bind.packageVersion.Setup) and I get error Unresolved bind-time variable !(bind.packageVersion.Setup)Iliac
Have you referenced the Setup project in the Bundle project?Ignition
Yes <ProjectReference Include="..\Setup\Setup.wixproj"><Name>Setup</Name>Iliac
Odd, I do this all the time. Can you check your solution configuration and make sure the bundle project depends on setup and also that they are both the same platform (mine are all x86).Ignition
Bootstrapper & Setup platform: x86 (nothing else in dropdown). Solution Project Dependencies > 'Bootstrapper' project Depends on: [x] BootstrapperCustom [x] Setup. I am using latest WiX 3.7 and VS2k12.Iliac
Here is a complete example show this working dl.dropboxusercontent.com/u/4752262/BurnVersion.zipIgnition
@brockhensley, the name in the !(bind.packageVersion.Setup) e.g. Setup, needs to be the contents of the Id attribute specified in the MsiPackage. So it should be something like <MsiPackage Id="SetUp" SourceFile="$(var.Setup.TargetPath)" />Barbell
@NeilSleightholm How to include this version information to set as the OutputName in a burn bootstrapper ?Gelderland
I
8

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>
Iliac answered 25/9, 2013 at 21:51 Comment(5)
Hmmm... when I try this I get "Undefined preprocessor variable '$(var.BuildVersion)'." I'm trying to grab version, company name, product name, etc from the Assembly. (I'm just using your "BeforeBuild" section and replacying MyApp with my app path/name)Edgeways
Make sure the path to the exe or dll is correct, it is relative to where your Bootstrapper project lies, this is working for me I'm not sure why you would get that error if it is able to find the fileIliac
Thanks dirt, I managed to get the buildversion to work. I was trying to extend your technique and also grab Company, Product, etc from the Assembly metadata, but wasn't able to get that to work.Edgeways
I'm having some difficulty with this. I am packaging an msi instead of an exe; therefore, I have another wix project for that the msi. I tried copying the BeforeBuild tasks (i excluded the afterbuild portion), but couldn't get it to work. Being uncertain if wix setup projects supported define constants. I tried an alternate route. I have tried <CreateProperty Value="%(AssemblyVersion.Version)"> <Output TaskParameter="Value" PropertyName="BuildVersion" /> </CreateProperty> but the property is never set. Any advice is appreciated.Seafood
This did not work for me. I set message tasks showing that the property for BuildVersion was set; however, the property lost scope and a resulted in error: 'Undefined preprocessor variable '$(var.BuildVersion' Note that I am using a setup project and not a bootstrapper project.Seafood

© 2022 - 2024 — McMap. All rights reserved.