创建CrystalDecisions.CrystalReports.Engine.ReportDocument对象时应用崩溃
Crystal Report 11.5 初始化顺序崩溃解决方案
问题根因
崩溃由Crystal Report 11.5 托管封装类(ReportDocument属于CrystalDecisions.CrystalReports.Engine托管程序集)和COM原生接口(CRAXDDRT是ActiveX设计时运行库)的初始化冲突导致,二者共享底层运行时资源,默认顺序初始化会触发资源锁竞争或上下文不匹配。
解决方案
- 方案1:调换初始化顺序,优先初始化COM组件,再初始化托管
ReportDocument
' 正确初始化顺序 objCrystalApp = New CRAXDDRT.Application RepDoc = New ReportDocument
CRAXDDRT作为COM组件需要先占用底层运行时的注册上下文,后续初始化的托管封装类会自动适配已存在的COM运行时实例,不会触发冲突。
- 方案2:初始化前显式清理残留COM对象
如果程序之前有未正确释放的Crystal Report COM实例残留,会导致新初始化时资源访问冲突,初始化前强制GC清理即可解决:
' 初始化前清理残留资源 If Not objCrystalApp Is Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(objCrystalApp) objCrystalApp = Nothing End If GC.Collect() GC.WaitForPendingFinalizers() ' 按正确顺序初始化 objCrystalApp = New CRAXDDRT.Application RepDoc = New ReportDocument
- 方案3:修改项目配置适配COM运行时
在项目app.config的configuration节点下添加如下配置,强制托管程序集使用兼容COM的运行时激活策略,避免.NET运行时隔离COM上下文导致的冲突:
<configSections> <sectionGroup name="businessObjects"> <sectionGroup name="crystalReports"> <section name="runtimeSettings" type="CrystalDecisions.Shared.RuntimeSettings, CrystalDecisions.Shared, Version=11.5.3700.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" allowLocation="true" allowDefinition="Everywhere"/> </sectionGroup> </sectionGroup> </configSections> <businessObjects> <crystalReports> <runtimeSettings> <add key="useLegacyV2RuntimeActivationPolicy" value="true"/> </runtimeSettings> </crystalReports> </businessObjects>
注意事项
- 不要在同一线程内重复初始化
ReportDocument和CRAXDDRT.Application实例,建议全局单例复用两个对象 - 程序退出时需按初始化逆序显式释放资源,避免COM内存泄漏:
If RepDoc IsNot Nothing Then RepDoc.Close() RepDoc.Dispose() RepDoc = Nothing End If If objCrystalApp IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(objCrystalApp) objCrystalApp = Nothing End If GC.Collect() GC.WaitForPendingFinalizers()
内容的提问来源于stack exchange,提问作者Hamid
相关产品推荐
相关产品推荐

