Wix+Visual Studio C#项目合并Crystal Reports时遇错误求助
问题描述
我有一个12年前用Visual Studio C# + Installshield开发的桌面应用项目,现在计划用Wix替代过时的Installshield重新制作64位MSI安装包(项目已升级到VS2022 64位,仅面向64位设备分发)。其他功能都正常,唯独集成Crystal Reports导出硬拷贝功能时,通过CR合并模块实现出现大量编译错误。
Wix配置代码
Folders.wsx
<Fragment> <StandardDirectory Id="ProgramFiles64Folder"> <!-- 在Program Files下创建YOURCOMPANY\MyApp --> <Directory Id="ManufacturerFolder" Name="YourCompany"> <Directory Id="INSTALLFOLDER" Name="$(var.Manufacturer)\$(var.Name)" /> </Directory> </StandardDirectory> <StandardDirectory Id="ProgramMenuFolder"> <!-- 定义开始菜单中的文件夹名称 --> <Directory Id="ApplicationProgramsFolder" Name="$(var.Name)" /> </StandardDirectory> </Fragment>
Folders.wsx与Components.wxs共享代码
<!-- ICE83要求:AdvertiseExecuteSequence中必须包含MsiPublishAssemblies --> <Fragment> <InstallExecuteSequence> <!-- 移除旧版本安装中的已注册程序集 --> <MsiUnpublishAssemblies Sequence="1501" /> <!-- 注册新的CLR/Win32程序集 --> <MsiPublishAssemblies Sequence="1502" /> </InstallExecuteSequence> <AdvertiseExecuteSequence> <!-- 广告安装时注册程序集 --> <MsiPublishAssemblies Sequence="1502" /> </AdvertiseExecuteSequence> </Fragment>
Components.wsx
<Fragment> <DirectoryRef Id="INSTALLFOLDER"> <Merge Id="CRMerge64" SourceFile=".\res\CRforVS64_mergemodules\CRRuntime64_13_0_38.msm" DiskId="1" Language="1033"> </Merge> </DirectoryRef> </Fragment>
Package.wxs
<Feature Id="Main" Title="DUCX" AllowAbsent="no" ConfigurableDirectory="INSTALLFOLDER" AllowAdvertise="no" Description="核心必须安装组件"> <ComponentGroupRef Id="Components" /> <MergeRef Id="CRMerge64" /> </Feature>
编译错误与警告
使用64位CRRuntime合并模块编译时,出现以下问题:
错误
- ICE03: 表Font的File_列在_Validation表中缺少规范(或数据库版本过旧)
- ICE83: MsiPublishAssemblies操作必须存在于AdvtExecuteSequence表中
- 约20条ICE80错误:64位组件
win64_x64.3A9D2E22.089E.41EE.8696.6BE8C981E0DD使用了32位目录
警告
- 目录表中主键为
ProgramMenuFolder的记录无法从合并模块合并,疑似主键冲突 - ICE03: Registry表的Registry列字符串溢出(超过允许长度)
- ICE51: TTF字体
Code39AzaleaNarrow1.ttf.4A374CE0.8940.4C87.88CE.BACA5530C9DD同时设置了标题,不符合规范
注释掉<MergeRef>后所有错误消失,确认问题来自CR合并模块。请问我的配置哪里有问题?
解决方案
1. 修复ICE80(64位组件用32位目录)
Crystal Reports的64位合并模块可能内部包含32位目录定义,需确保整个MSI包明确标记为64位:
- 在
Package元素中添加Platform="x64"属性,强制MSI为64位:
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" Platform="x64" />
- 在
Merge元素中添加Win64="yes",明确标记合并模块为64位:
<Merge Id="CRMerge64" SourceFile=".\res\CRforVS64_mergemodules\CRRuntime64_13_0_38.msm" DiskId="1" Language="1033" Win64="yes"> </Merge>
2. 修复ICE83问题
合并模块可能覆盖了序列配置,可调整MsiPublishAssemblies的执行顺序,确保其在合并模块的序列前运行:
<AdvertiseExecuteSequence> <MsiPublishAssemblies Sequence="100" /> </AdvertiseExecuteSequence>
如果不需要广告安装功能,也可在Package中设置DisableAdvertise="yes",跳过相关ICE检查。
3. 解决ProgramMenuFolder冲突
合并模块自带ProgramMenuFolder定义,与自定义配置冲突,可二选其一:
- 删除自定义的ProgramMenuFolder相关代码,直接使用合并模块的配置;
- 修改自定义的
ApplicationProgramsFolder名称,与合并模块中的目录名称保持一致。
4. 处理ICE03、ICE51警告
这些属于合并模块自身的规范问题,不影响功能的话可直接禁用相关ICE检查:
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" Platform="x64" SuppressIces="ICE03,ICE51" />
替代方案:使用独立CR Runtime安装包
如果合并模块问题过多,建议改用独立安装包:
- 下载对应版本的64位CR Runtime静默安装包;
- 在Wix中添加自定义动作,检测系统是否已安装CR Runtime;
- 未安装时,通过自定义动作静默执行安装包。
内容的提问来源于stack exchange,提问作者RouseA
相关产品推荐
相关产品推荐

