WiX 6.0.2:如何向Bundle中的MsiPackage传递ADDLOCAL参数?
Wix Bundle中给第三方MSI传递ADDLOCAL属性的解决方案
问题背景
我用以下命令构建包含MsiPackage链的Bundle:
wix build -ext WixToolset.BootstrapperApplications.wixext -arch x64 -cc c:\cabcache backend-bundle.wxs -outputtype bundle -o backend.exe
链里的第三方组件单独安装时需要执行:
SomeThirdPartyRuntime.msi ADDLOCAL=Complete,SomeExtension,SomeFeature
但直接用MsiProperty设置ADDLOCAL时触发错误:
<MsiPackage Id="SomeThirdPartyRuntime64" Vital="yes" SourceFile="$(var.SomeThirdPartyRuntime)" ForcePerMachine="true"> <MsiProperty Name="ADDLOCAL" Value="Complete,SomeExtension,SomeFeature"/> </MsiPackage>
error WIX0365: The 'ADDLOCAL' MsiProperty is controlled by the bootstrapper and cannot be authored. (Illegal properties are: 'ACTION', 'ADDLOCAL', 'ADDSOURCE', 'ADDDEFAULT', 'ADVERTISE', 'ALLUSERS', 'REBOOT', 'REINSTALL', 'REINSTALLMODE', or 'REMOVE'.) Remove the MsiProperty element.
需要解决这个问题,且不能让终端用户自行配置多个MSI。
可行解决方案
方法1:把MSI包装成ExePackage调用msiexec
利用ExePackage支持InstallArguments的特性,通过msiexec.exe来调用第三方MSI,直接传递ADDLOCAL参数:
<ExePackage Id="SomeThirdPartyRuntime64" Vital="yes" SourceFile="path/to/msiexec.exe" InstallArguments="/i "[SourceDir]SomeThirdPartyRuntime.msi" ADDLOCAL=Complete,SomeExtension,SomeFeature /qn" RepairArguments="/f "[SourceDir]SomeThirdPartyRuntime.msi" /qn" UninstallArguments="/x "[SourceDir]SomeThirdPartyRuntime.msi" /qn" DetectCondition="SomeThirdPartyRuntimeInstalled" Compressed="yes"> <Payload SourceFile="$(var.SomeThirdPartyRuntime)" Name="SomeThirdPartyRuntime.msi"/> </ExePackage>
- 必须添加MSI作为ExePackage的Payload
DetectCondition需要自定义,比如检查该组件安装后生成的注册表项或特定文件,用来判断是否已安装/qn是静默安装参数,可根据需求调整为其他交互级别
方法2:用WixBal扩展的SetMsiProperty动态设置属性
通过WixToolset.Bal.wixext提供的SetMsiProperty元素,在Bundle运行时动态给MSI注入ADDLOCAL属性:
- 构建命令中添加Bal扩展:
wix build -ext WixToolset.BootstrapperApplications.wixext -ext WixToolset.Bal.wixext -arch x64 -cc c:\cabcache backend-bundle.wxs -outputtype bundle -o backend.exe
- 在Bundle的
Chain里,把SetMsiProperty放在对应的MsiPackage之前:
<Chain> <SetMsiProperty Id="SetThirdPartyADDLOCAL" MsiPackageId="SomeThirdPartyRuntime64" Property="ADDLOCAL" Value="Complete,SomeExtension,SomeFeature"/> <MsiPackage Id="SomeThirdPartyRuntime64" Vital="yes" SourceFile="$(var.SomeThirdPartyRuntime)" ForcePerMachine="true"/> </Chain>
这种方法不用修改MSI的包装方式,直接通过Burn的自定义动作绕过对ADDLOCAL的直接控制限制,在安装阶段动态设置属性值。
内容的提问来源于stack exchange,提问作者crusy
相关产品推荐
相关产品推荐

