我继承了一个旧的Windows表单应用程序,其中包括使用Crystal报表生成PDF:s以进行打印。我尝试使用Crystal Reports for Visual Studio 2010
组件而不是旧版本的组件,但我在检查客户端计算机上是否安装了所需的版本时遇到问题。我希望即使没有安装Crystal也可以使用该应用程序,当然除了PDF生成之外。
该应用程序执行与此类似的操作(不相关的详细信息除外):
try {
ReportDocument report = new ReportDocument();
//do something with the report, produce pdf etc
}
catch(Exception e) {
Log.Write(e);
throw();
}
然后在调用表单中再次捕获异常,然后显示一些信息,包括下载正确的Crystal安装文件的链接。
我认为这之前一直在工作,但在我更新到Crystal组件13之后。#。#。#这已经不够了。 ReportDocument report = new ReportDocument();
触发System.TypeInitializationException
离开report
为空。所以我没有什么可以随后处理的。但是,某些会被创建,因为稍后,Finalizer
会运行,导致另一个System.TypeInitializationException
被抛出,从而导致应用程序崩溃。
如何以不会在Finalizer线程上导致后续异常的方式运行new ReportDocument();
之前测试Crystal是否已安装?
答案 0 :(得分:2)
尝试使用Reflection加载Type。这样可以防止实例化,但可以验证是否可以创建Type。
答案 1 :(得分:0)
决定接受@PhillipH的回答,因为他指出了我的反思方向。但我仍然希望展示我实际做的事情。
我在Could not load file or assembly 'CrystalDecisions.ReportAppServer.CommLayer, Version=13.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304' or one of its dependencies. The system cannot find the file specified.
行上遇到的例外是(除其他事项外):
System.Reflection.Assembly a = System.Reflection.Assembly.ReflectionOnlyLoad("CrystalDecisions.ReportAppServer.CommLayer, Version=13.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304");
所以为了测试,我添加了这个:
ReportDocument
在新的Reflection
之前。当没有安装Crystal时,这会抛出,调用表单会捕获它并显示“Here's如何下载和安装Crystal”表单。
免责声明:我不习惯与Finalizer
合作,所以我不能说这是好还是完全愚蠢。似乎工作,更改后没有<tr><td onClick="doSomething('$param')">$param</td></tr>
错误。
答案 2 :(得分:0)
我只是检查装配路径:
If Not Directory.Exists(" C:\Windows\assembly\GAC_MSIL\CrystalDecisions.CrystalReports.Engine") Then
InstallCrystalRuntime()
End If