配置 WiX 以自动设置产品版本属性? [英] Configure WiX to automatically set Product Version attribute?
问题描述
目前,每当我构建我的包时,我必须像这样手动增加 Product.wxs 文件中的 Version 属性:
我想实现自动化,以简化构建过程.我们对 exe/dll 文件使用以下版本控制方案:
major.minor.special.build
special 几乎从未使用过,并设置为 0,并且约定是将打包的 MSI 版本如下,因为您只能使用三个数字:
major.minor.build
我见过的唯一解决方案是让您获取另一个项目的 4 位数版本,然后截断构建版本,因此您最终会得到这样的结果:
major.minor.special
显然这不适用于我们的方案,因为我们丢失了内部版本号.我怎样才能抓住 major.minor.build
,忽略特殊的?
我使用包含文件中的 WiX 变量,每次构建时都会重新生成该变量.
由于我的项目是 .wixproj (MSBuild/Visual Studio),我只是将版本提取和格式设置在其中作为自定义的内联 MSBuild 任务进行编码,并在 BeforeBuild 目标中调用它.
在下面的例子中,我得到了产品主要装配体的装配体版本.您可以将其编码为您想要的任何版本.
使用 WiX 包含和变量
<?包括 ProductVersion.wxi?><Product Version="$(var.ProductVersion)" ...>…</Wix>
示例 ProductVersion.wxi
<?define ProductVersion=1.0.38549?></包括>
我建议在项目中包含 .wxi 文件,以便它在解决方案视图中可见.而且,由于它是生成的,我建议将其从源代码管理中排除.
编辑 WixProj
.wixproj 既是 Visual Studio 项目文件,也是 MSBuild 项目文件.要在 Visual Studio 中编辑 Visual Studio 项目文件,请选择
Currently, whenever I build my package, I have to manually increment the Version attribute inside Product.wxs file like this:
<Product
Id = "*"
Version="4.1.3"
I'd like to automate that, to streamline the build process. We use the following versioning scheme for exe/dll files:
major.minor.special.build
The special is almost never used, and set to 0, and the convention was to version the packaged MSI's as following, since you can only use three numbers:
major.minor.build
The only solutions I've seen let you grab the 4 digit version of the other project, and then truncate the build version, so you end up with this:
major.minor.special
Clearly that won't work with our scheme, since we lose the build number. How can I grab major.minor.build
, ignoring special?
I use a WiX variable from an include file that I regenerate with every build.
Since my project is a .wixproj (MSBuild/Visual Studio), I just code the version extraction and formatting right in there as a custom, inline MSBuild task and call it in the BeforeBuild target.
In the example below, I get the assembly version of the main assembly of the product. You can code it up for any version you want.
Using WiX Include and variable
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include ProductVersion.wxi?>
<Product Version="$(var.ProductVersion)" …>
…
</Wix>
Example ProductVersion.wxi
<Include>
<?define ProductVersion=1.0.38549?>
</Include>
I recommend including the .wxi file in the project so it's visible in the Solution View. And, since it's generated, I recommend excluding it from source control.
Edit WixProj
A .wixproj is both a Visual Studio project file and an MSBuild project file. To edit a Visual Studio project file in Visual Studio, pick a tutorial or extension.
BeforeBuild Target
MSBuild systems, including WiX's, offer BeforeBuild and AfterBuild targets, as explained in the .wixproj comments.
Just pull the target out of the comments and add a task call.
<Target Name="BeforeBuild">
<GenerateProductVersion AssemblyPath='../wherever/whatever.exe' />
</Target>
MSBuild Inline Task
Task code can be in its own MSBuild file or even DLL for reuse. Or, for a scripting approach, it can be inline.
There are 3 parts to this task:
- File path parameter (because it would vary from project to project)
- Extraction (with logging)
- Include generation (to a hard-coded name in the project folder because it doesn't need to vary)
.
<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>
Making EXE path more visible
All of this is hidden too well in the project file. Many project designers have a Build tab that allows entering name-value pairs into the build. That provides a mechanism to raise the path up out of the XML.
<Target Name="BeforeBuild">
<GenerateProductVersion AssemblyPath='$([System.Text.RegularExpressions.Regex]::Match(";$(DefineConstants);", ";VersionExtractionPath=(?<path>.*?);").Groups["path"].Value)' />
</Target>
这篇关于配置 WiX 以自动设置产品版本属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!