如何在Wix Burn引导程序中自动同步MSI的产品名称与版本号
问题场景
现有bundle.wxs代码片段:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"> <?define ProductName="YOUVI Panel v5.0.9.0" ?> <Bundle Name="$(var.ProductName)" Version="5.0.9.0" Manufacturer="Company" UpgradeCode="Some GUID" IconSourceFile ="Resources/youvi_panel.ico"> <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense"> <bal:WixStandardBootstrapperApplication LicenseFile="Resources/license_en.rtf" LogoFile="Resources/dialog.jpeg" ThemeFile="Resources/CustomTheme.xml" LocalizationFile="Resources/CustomTheme.wxl"/> </BootstrapperApplicationRef> <Chain> <MsiPackage Id ="Setup" DisplayName ="YOUVI.PanelService.Installer" DisplayInternalUI ="no" SourceFile="$(var.YOUVI.PanelService.Installer.TargetPath)" Compressed="yes" Vital="yes" Permanent="no"/> </Chain> </Bundle>
以及product.wxs(生成Installer.msi)的代码片段:
<Product Id="*" Name="YOUVI Panel v!(bind.FileVersion.fil33CD3061EBAE985C253BB51BC48FBD3C)" Language="!(loc.LANG)" Version="!(bind.FileVersion.fil33CD3061EBAE985C253BB51BC48FBD3C)" Manufacturer="Company" UpgradeCode="Some GUID">
需求:让bundle.wxs自动同步product.wxs中的产品名称和版本号,无需手动修改引导程序配置,保证发布时两者版本与名称完全一致。
解决方案
下面两种是最常用的实现方式,优先推荐第一种:
方法一:通过项目引用传递预处理器变量
这是最简单直接的方式,利用WiX的项目依赖传递变量:
在MSI项目中定义预处理器变量
打开MSI项目(即product.wxs所属项目)的属性面板,切换到Build选项卡,在Define preprocessor variables输入框中添加:ProductVersion=!(bind.FileVersion.fil33CD3061EBAE985C253BB51BC48FBD3C);ProductName=YOUVI Panel v!(bind.FileVersion.fil33CD3061EBAE985C253BB51BC48FBD3C)注意替换其中的文件ID
fil33CD3061EBAE985C253BB51BC48FBD3C为你项目中实际对应主程序的文件ID。给Bundle项目添加MSI项目引用
在Visual Studio中右键Bundle项目 → Add → Reference,选择你的MSI项目,确认添加。修改bundle.wxs的变量引用
删掉手动定义的ProductName常量,直接引用MSI项目传递过来的变量:<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"> <Bundle Name="$(var.YOUVI.PanelService.Installer.ProductName)" Version="$(var.YOUVI.PanelService.Installer.ProductVersion)" Manufacturer="Company" UpgradeCode="Some GUID" IconSourceFile ="Resources/youvi_panel.ico"> <!-- 其余代码保持不变 --> </Bundle>这里的
YOUVI.PanelService.Installer是你的MSI项目名称,根据实际项目名修改即可。
方法二:从已构建的MSI文件读取属性
如果不想依赖项目引用,可以通过脚本从生成的MSI中提取属性,再传递给Bundle:
- 在Bundle项目的构建事件中添加提取命令
打开Bundle项目属性 → Build Events,在Post-build event command line中添加(根据你的MSI生成路径调整)::: 提取MSI内容到临时目录 dark.exe -x temp "..\YOUVI.PanelService.Installer\bin\Release\YOUVI.PanelService.Installer.msi" :: 提取ProductName和ProductVersion属性 findstr /C:"ProductName" temp\Product.wxs > productname.txt findstr /C:"ProductVersion" temp\Product.wxs > productversion.txt :: 清理临时文件 rmdir /S /Q temp - 在bundle.wxs中读取提取的属性
通过预处理器读取文本文件内容,替换原有的名称和版本定义。这种方法相对繁琐,仅在无法使用项目引用时考虑。
注意事项
- 确保MSI项目中的文件ID正确对应包含版本信息的主程序文件,否则绑定的版本号会出错。
- 使用项目引用时,Visual Studio会自动处理构建顺序,确保MSI先于Bundle构建;如果是手动编写构建脚本,需要手动调整构建顺序。
内容的提问来源于stack exchange,提问作者KarsaOrlong1981
相关产品推荐
相关产品推荐

