How to read content of text file in Wix Toolset Bo

2019-08-29 18:47发布

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">

2条回答
Fickle 薄情
2楼-- · 2019-08-29 18:58

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

查看更多
狗以群分
3楼-- · 2019-08-29 19:04

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:

查看更多
登录 后发表回答