如何在WiX Bundle中实现首个安装程序向第二个传递安装目录?
在WiX Bundle中传递第一个安装程序的自定义安装目录给第二个
当然有可行方案,核心思路是让第一个安装程序把用户选择的目录持久化(比如写入注册表),再通过Bundle读取这个值传递给第二个安装程序,下面是两种具体实现方式:
方法1:修改第一个MSI写入自定义注册表项
这是最灵活的方式,适合你能修改第一个MSI源码的场景:
在第一个MSI中添加注册表写入逻辑
在第一个MSI的Product.wxs里,给安装目录所在的组件添加注册表项,把用户选择的路径存进去:<DirectoryRef Id="INSTALLFOLDER"> <Component Id="InstallPathRegistry" Guid="YOUR-GUID-HERE"> <RegistryValue Root="HKLM" Key="Software\[Manufacturer]\[ProductName]" Name="InstallDirectory" Type="string" Value="[INSTALLFOLDER]" KeyPath="yes" /> </Component> </DirectoryRef>记得把这个组件包含到对应的Feature中,确保安装时会创建该注册表项。
在Bundle中读取注册表值
在Bundle的Bundle.wxs里定义变量,通过注册表搜索获取第一个MSI的安装路径:<Variable Name="FirstAppInstallPath" Type="string" /> <util:RegistrySearch Id="GetFirstAppPath" Root="HKLM" Key="Software\[Manufacturer]\[ProductName]" Value="InstallDirectory" Variable="FirstAppInstallPath" After="InstallInitialize" />After="InstallInitialize"确保搜索动作在第一个MSI安装完成后执行,保证能读到最新的路径。传递路径给第二个MSI
在第二个MsiPackage节点中,把读取到的变量作为属性传递给第二个MSI:<MsiPackage SourceFile="path/to/second.msi"> <MsiProperty Name="TARGETDIR" Value="[FirstAppInstallPath]" /> </MsiPackage>注意:第二个MSI需要提前定义
TARGETDIR(或你自定义的属性名)来接收这个路径,确保安装逻辑能正确使用该属性。
方法2:读取MSI默认卸载注册表项(无需修改第一个MSI)
如果第一个MSI是标准打包的,Windows会自动在卸载注册表项中记录它的安装路径,你可以直接读取这个默认路径:
<Variable Name="FirstAppInstallPath" Type="string" /> <util:RegistrySearch Id="GetFirstAppPath" Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\{FIRST-MSI-PRODUCT-CODE}" Value="InstallLocation" Variable="FirstAppInstallPath" After="InstallInitialize" />
替换{FIRST-MSI-PRODUCT-CODE}为第一个MSI的产品GUID,后续传递给第二个MSI的步骤和方法1一致。
关键注意事项
- 若第一个MSI是32位程序,在64位系统上注册表会写入
HKLM\Software\WOW6432Node路径,需要在RegistrySearch中添加Win64="no"参数适配。 - 调整
RegistrySearch的After属性时机,确保在第一个MSI安装完成后再执行搜索,避免读取到旧值或空值。
内容的提问来源于stack exchange,提问作者Fede
相关产品推荐
相关产品推荐

