配置WiX以自动设置产品版本属性?

时间:2017-10-19 17:03:27

标签: wix

目前,无论何时构建我的包,我都必须手动增加Product.wxs文件中的Version属性,如下所示:

<Product 
    Id = "*"
    Version="4.1.3"

我希望自动化,以简化构建过程。我们对exe / dll文件使用以下版本控制方案:

major.minor.special.build

特殊功能几乎从不使用,并设置为0,惯例是将打包的MSI版本如下,因为您只能使用三个数字:

major.minor.build

我见过的唯一解决方案让你抓住另一个项目的4位数版本,然后截断构建版本,所以你最终得到了这个:

major.minor.special
显然,由于我们丢失了内部版本号,因此无法使用我们的方案。如何抓住major.minor.build,忽略特殊?

1 个答案:

答案 0 :(得分:5)

我使用包含文件中的WiX变量,我在每次构建时都会重新生成。

由于我的项目是.wixproj(MSBuild / Visual Studio),我只是将版本提取和格式化作为自定义内联MSBuild任务编写,并在BeforeBuild目标中调用它。

在下面的示例中,我获得了产品主装配的装配版本。您可以为任何您想要的版本编写代码。

使用WiX包含和变量

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <?include ProductVersion.wxi?>
  <Product Version="$(var.ProductVersion)" …>
…
</Wix>

示例ProductVersion.wxi

<Include>
  <?define ProductVersion=1.0.38549?>
</Include> 

我建议在项目中包含.wxi文件,以便在解决方案视图中显示。并且,由于它已生成,我建议将其从源代码管理中排除。

编辑WixProj

<。> .wixproj既是Visual Studio项目文件又是MSBuild项目文件。要在Visual Studio中编辑Visual Studio项目文件,请选择tutorial or extension

BeforeBuild Target

MSBuild系统(包括WiX)提供BeforeBuild和AfterBuild目标,如.wixproj评论中所述。

只需从评论中提取目标并添加任务调用。

<Target Name="BeforeBuild">
  <GenerateProductVersion AssemblyPath='../wherever/whatever.exe' />
</Target>

MSBuild内联任务

任务代码可以在自己的MSBuild文件中,甚至可以在DLL中重复使用。或者,对于脚本方法,它可以是内联的。

这项任务有三个部分:

  • 文件路径参数(因为它会因项目而异)
  • 提取(带日志记录)
  • 包括生成(到项目文件夹中的硬编码名称,因为它不需要改变)

<UsingTask TaskName="GenerateProductVersion" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
  <AssemblyPath ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
  <Reference Include="System.Xml" />
  <Reference Include="System.Xml.Linq" />
  <Using Namespace="System" />
  <Using Namespace="System.Xml.Linq" />
  <Using Namespace="System.Reflection" />
  <Code Type="Fragment" Language="cs"><![CDATA[
    var assemblyVersion = AssemblyName.GetAssemblyName(AssemblyPath).Version;
    var productVersion = String.Format("{0}.{1}.{2}", assemblyVersion.Major, assemblyVersion.Minor, assemblyVersion.Revision);
    Log.LogMessage(MessageImportance.High, "ProductVersion=" + productVersion + " extracted from assembly version of " + AssemblyPath);
    new XDocument(
        new XElement("Include", 
            new XProcessingInstruction("define", "ProductVersion=" + productVersion)))
        .Save("ProductVersion.wxi");
  ]]></Code>
</Task>
</UsingTask>

使EXE路径更加可见

所有这些都隐藏在项目文件中。许多项目设计人员都有一个Build选项卡,允许在构建中输入名称 - 值对。这提供了一种机制来提高XML的路径。

<Target Name="BeforeBuild">
  <GenerateProductVersion AssemblyPath='$([System.Text.RegularExpressions.Regex]::Match(";$(DefineConstants);", ";VersionExtractionPath=(?&lt;path&gt;.*?);").Groups["path"].Value)' />
</Target>

enter image description here