【发布时间】:2009-03-09 12:32:19
【问题描述】:
我编写了一个应用程序及其 WiX 安装程序,并使用 subversion 将其置于版本控制之下。当 WiX 安装程序构建时,我希望它的版本号是应用程序的当前构建版本。我该如何做到这一点?我使用 c# 编写应用程序。
注意我正在使用 ccnet 来构建这个项目
【问题讨论】:
我编写了一个应用程序及其 WiX 安装程序,并使用 subversion 将其置于版本控制之下。当 WiX 安装程序构建时,我希望它的版本号是应用程序的当前构建版本。我该如何做到这一点?我使用 c# 编写应用程序。
注意我正在使用 ccnet 来构建这个项目
【问题讨论】:
您可以使用Product/@Version="!(bind.FileVersion.FileId)"(将FileId 替换为您要从中获取版本号的文件的Id),light.exe 将使用引用的文件的版本填充该值FileId。
【讨论】:
我在我的一个项目中通过编写预处理器扩展来从我的可执行文件中读取文件版本来做到这一点。所以 WiX 文件看起来像:
<?define ProductName="$(fileVersion.ProductName($(var.MyApp.TargetPath)))" ?>
<?define CompanyName="$(fileVersion.CompanyName($(var.MyApp.TargetPath)))" ?>
<?define ProductVersion="$(fileVersion.ProductVersion($(var.MyApp.TargetPath)))" ?>
<Product
Id="<product ID>"
Name="$(var.ProductName)"
Version="$(var.ProductVersion)"
Manufacturer="$(var.CompanyName)"
Language="1033"
UpgradeCode="<upgrade code>">
我已经在 CodePlex 上发布了 in 的代码:http://wixfileversionext.codeplex.com/
【讨论】:
如果有人正在寻找一个实际的 XML 示例,这适用于 .NET 程序集(您不必执行 Assembly 或 KeyPath 属性)。我用 [...] 占位符消除了不相关的代码:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product [...] Version="!(bind.fileVersion.MyDLL)">
[...]
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="INSTALLDIR" Name="MyDLLInstallLocation">
<Component Id="MainLib" Guid="[...]">
<File Id="MyDLL" Name="MyDll.dll" Source="MyDll.dll" />
[...]
</Component>
[...]
</Directory>
</Directory>
</Directory>
</Product>
</Wix>
【讨论】:
!(bind.fileVersion.MyDLL),它使用第三部分引用<File Id="MyDLL"... 部分
这是一种非常简单的方法,可以使用 BeforeBuild Target 和 DefineConstants 让您的 Bootstrapper Bundle 版本与您的 MyApp AssemblyVersion 匹配。
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>
【讨论】:
<Bundle> 上方的某个位置定义了var.ProductName 和var.BuildVersion?
BeforeBuild 目标,因此如果您在 IDE 中构建,可能需要明确指定 AfterTargets="AfterResolveReferences"
您可以将版本传递给安装项目的 MSBuild 脚本,就像传递给应用程序的构建脚本一样。
例如,如果您的 CI 系统定义了变量 AppVersion 和 BuildNumber,并将它们传递给您的 MSBuild 脚本,那么您的 wixproj 可以创建一个相应的 Version 属性,并将其转发给 Wix,如下所示:
<PropertyGroup>
<Version Condition=" '$(BuildNumber)' == '' ">0.0.1</Version>
<Version Condition=" '$(BuildNumber)' != '' ">$(AppVersion).$(BuildNumber)</Version>
<DefineConstants>Version=$(Version)</DefineConstants>
</PropertyGroup>
Version 的第一个定义为您在本地构建时提供了一个默认值。无论最终结果如何,都会成为 Wix 中的 Version 变量。在这样的 wsx 文件中使用它:
<Product Version="$(var.Version)" ...>
<Package Description="$(var.ProductName) $(var.Version): $(var.ProductDescription)" ... />
我喜欢在描述中包含版本,以便可以轻松地从窗口资源管理器(作为详细信息视图或属性页面中的一列)查找,而与文件名无关。
与从文件中读取版本相比,将版本作为变量传递给您更多的控制权。当您从文件中读取时,您将获得程序化版本的所有 4 个部分。但是,ProductVersion 仅设计为使用前 3 部分。
【讨论】:
<Version Condition=" '$(BuildVersionOfAsm)' != '' ">$(BuildVersionOfAsm)</Version> 而 BuildVersionOfAsm 是 devops 管道中的一个变量。
这看起来与您想要完成的目标相当接近。看看巡航控制中的等价物。
http://www.ageektrapped.com/blog/setting-properties-for-wix-in-msbuild/
【讨论】: