You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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安装包

如果合并模块问题过多,建议改用独立安装包:

  1. 下载对应版本的64位CR Runtime静默安装包;
  2. 在Wix中添加自定义动作,检测系统是否已安装CR Runtime;
  3. 未安装时,通过自定义动作静默执行安装包。

内容的提问来源于stack exchange,提问作者RouseA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 07:45:55