1

I am using the WiX toolset to build an installer, I want to read the version from a text file. The text file is located in mybootstrapper like below:

Wix toolset Bootstrapper direcotry tree

below is the code where i want to read the content of text file

<Bundle IconSourceFile='product.ico'
Name="Retail Grip"
Version="Version.txt" <!-- i know this is not correct -->
Manufacturer="Company Name"
UpgradeCode="PUT-GUID-HERE">
Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
Usman Ali
  • 778
  • 8
  • 21
  • Did you see: https://stackoverflow.com/questions/19241971/how-to-read-a-string-from-a-file-wix – Stephu Jun 24 '18 at 10:33
  • Where does this version.txt come from? Is it necessary independent of the goal of giving the bundle a version? – Tom Blodget Jun 24 '18 at 13:15
  • I am wondering if that [Wax tool](https://youtu.be/-wyUxQux7xY?t=65) has anything to do with it? I have never used it before. – Stein Åsmul Jun 24 '18 at 13:21
  • i have build separate project to do all upgrade and updates. for example updating text file on the server in order to notify for updates, creating zip file of exe and other file and then upload to server etc, the reason for reading version from text file is to also control it from that separate project. sorry for bad explanation. – Usman Ali Jun 24 '18 at 13:28
  • @Stein actually i'm using Wax Tool, it is very useful plugin. by using wax tool i don't have to use candle.exe or light.exe or something else – Usman Ali Jun 24 '18 at 13:35
  • Just generate a [WiX Include file](http://wixtoolset.org/documentation/manual/v3/overview/preprocessor.html) with a define from the version.txt file (or instead of) at the build-time of either the separate project or the Bootstrapper project. A Bootstrapper build has to be for a specific version. – Tom Blodget Jun 30 '18 at 02:13
  • @TomBlodget i already added txt file, but now i want to read the content of that txt file and put the content in version. – Usman Ali Jun 30 '18 at 03:12

2 Answers2

3

Oh, it is a WiX bundle - and that's "Wax"? I hear it is a WiX tool of sorts? I am not sure exactly how it works (screenshot down the page in that link). Maybe there are restrictions on the use of compiler variables when using it?

I wrote the below before I saw that Wax file and I thought you had a normal WiX source and not a bundle source. Either way, let me add what I wrote and see if it helps. Similarities.

Also: Neil Sleightholm's WiX Burn Template (towards top). Give that link a spin first please.


In a regular WiX file you could use a pre-processor variable: $(var.CurrentVersion) (compiler variable). Something like this:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">

  <?define UpgradeCode="PUT-GUID-HERE"?>
  <?define CurrentVersion="1.0.0.0"?>

  <Product Id="*" Name="Sample" Language="1033" Version="$(var.CurrentVersion)"
           Manufacturer="Someone" UpgradeCode="$(var.UpgradeCode)">

  <...>

You can put the variables in its own "include file": Variables.wxi.

<Include>
   <?define UpgradeCode="PUT-GUID-HERE"?>
   <?define CurrentVersion="1.0.0.0"?>
</Include>

Larger sample here for this approach (do have a quick skim of this one).

And then include the file in your main WiX source:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">

  <?include Variables.wxi ?>

  <Product Id="*" Name="Sample" Language="1033" Version="$(var.CurrentVersion)"
           Manufacturer="Someone" UpgradeCode="$(var.UpgradeCode)">

  <...>

There are also localization variables: WiX (Windows Installer Xml), Create universal variables - link time variable resolution (light.exe), as opposed to the compile time resolution of pre-processor variables (candle.exe). Some context.


Some Relevant Links:

Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
  • thanks for your kind answer, i am checking it and will let you once completed. up vote for answering. i will accept it as answer if works. thanks again – Usman Ali Jun 24 '18 at 12:56
1

With WiX Include files, you can keep simple values separate from the bulk of the WiX markup. With WiX preprocessing, you can define named substitution values used in attributes or text nodes or conditional compilation, and then refer to them as $(var.name).

-- Version.wxi --

<?xml version="1.0" encoding="utf-8"?>
<Include>
  <?define Version="1.2.3" ?>
</Include>

-- Bundle.wxs --

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <?include "Version.wxi" ?>
  <Bundle 
    Version="$(var.Version)" 
    …

It is sometimes convenient to generate include files in a source project in anticipation of them being used downstream, or generate them as the first steps of a WiX project.

I see you are using Visual Studio for your WiX Bootstrapper project. A Visual Studio project is a specialized MSBuild project (as are most types of Visual Studio projects). That means you can put general MSBuild things into the project file. You can open the .wixproj file as an XML file in an XML editor (such as Visual Studio).

MSBuild allows you define new tasks either from an external DLL or inline, using a .NET language. In this case, a few lines of C# will do fine to define the task. Then you would invoke it before the main build tasks. Like many build systems that use MSBuild, WiX ensures the target BeforeBuild is executed before it gets to work. So, you just have to define BeforeBuild.

The task is named CreateVersionWxi.

  <UsingTask 
    TaskName="CreateVersionWxi" 
    TaskFactory="CodeTaskFactory" 
    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">

    <ParameterGroup />
    <Task>
      <Reference Include="System.Xml" />
      <Reference Include="System.Xml.Linq" />
      <Using Namespace="System.Xml.Linq" />
      <Code Type="Fragment" Language="cs"><![CDATA[
var version = File.ReadAllText("version.txt");
var wxi = 
  new XDocument(
    new XComment("*** GENERATED FILE. DO NOT EDIT ***"),
    new XElement("Include", 
      new XProcessingInstruction("define", "Version='" + version + "'")));
wxi.Save("version.wxi");
        ]]></Code>
    </Task>
  </UsingTask>

  <Target Name="BeforeBuild">
    <CreateVersionWxi />
  </Target>

Finally, if you add version.txt to your project with its Build Action, say, as Content, the project will be seen as needing to be rebuilt whenever version.txt changes. That will help if you have the WiX project open in Visual Studio while you are externally changing version.txt.

You don't need to add Version.wxi to your project but doing so increases its visibility to future maintainers.

Tip: Some Visual Studio users are more familiar with the Build Events on the project pages. To clue them in, you could enter this as a pre-build event command line: REM See the BeforeBuild target in the .wixproj file

Tom Blodget
  • 20,260
  • 3
  • 39
  • 72