当我想显示报告但未安装 Crystal 报告时,如何捕获所有异常?
How can I catch all exceptions, when I want to show a report and Crystal reports is not installed?
我有一个工具,它从数据库中读取数据,修改它,然后将其显示在 crystal 报告中,该报告显示在单独的 window.
中
该工具有时会被没有安装 Crystal 报告的人使用,所以我想显示特定的错误消息,告诉用户确切的操作(而不是现在的通用消息).
我打电话给 window 报告如下:
try
{
ReportWindow report = new ReportWindow(resultList);
report.Show();
}
catch (Exception ex)
{
this.LogAction("Could not open the report. To view it, you need to have Crystal Reports installed.", Notification.Error);
}
(为了这个问题简化了catch分支)
ReportWindow.xaml.cs
public ReportWindow(List<MeasureTestResult> measurement)
{
this._measurementList = measurement;
InitializeComponent();
}
ReportWindow.xaml
<Window x:Class="ResultFileViewer.Sources.ReportWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewer="clr-namespace:SAPBusinessObjects.WPF.Viewer;assembly=SAPBusinessObjects.WPF.Viewer">
<viewer:CrystalReportsViewer Name="CrystalReportsViewer1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Window>
ReportWindow
构造函数中的行 InitializeComponent();
抛出几个异常,例如 XamlParseException
或 InvalidCastException
。问题是,只有 XamlParseException
被捕获。其他异常仅由我的 DispatcherUnhandledException
属性 或我的 App.xaml.
处理
这是有问题的,因为它要么意味着当e.Handled设置为false时整个应用程序被关闭,要么在用户关闭应用程序后仍然存在僵尸进程,当e.Handled是设置为真。
如何在调用报告 window 的 class 中捕获当前未处理的异常?
我尝试了 this solution,但也没有捕捉到 InvalidCastException
。
我已经放弃尝试捕获流氓异常,因为我没有成功。
相反,如果安装了 Crystal Reports,我会尝试预先检测。我基本上找到了两个选择:
- 检查注册表中的特定条目
- 如果需要的程序集存在,请检查全局程序集缓存 (GAC)
注册表检查有一个缺点,它只包含一个相当通用的名称而不是特定的版本条目(例如 HKEY_CURRENT_USER\Software\SAP BusinessObjects\Crystal Reports for .NET Framework 4.0
)。
此外,如果您事先安装了 Crystal Reports 并卸载了它,无论出于何种原因,注册表项都会保留,因此也无法可靠地检查是否安装了 Crystal Reports。
所以我进行了 GAC 检查,我是这样做的:
try
{
// 13.0.2000.0 is Crystal Reports for VS 2010
// the first assembly is the most important one, but it also gets deployed by the project itself
// because of this I picked two additional assemblies to check for
var a = System.Reflection.Assembly.Load("CrystalDecisions.CrystalReports.Engine, Version=13.0.2000.0, Culture=neutral,PublicKeyToken=692fbea5521e1304");
result = a != null;
a = System.Reflection.Assembly.Load("CrystalDecisions.CrystalReports.TemplateEngine, Version=13.0.2000.0, Culture=neutral,PublicKeyToken=692fbea5521e1304");
result &= a != null;
a = System.Reflection.Assembly.Load("CrystalDecisions.Windows.Forms, Version=13.0.2000.0, Culture=neutral,PublicKeyToken=692fbea5521e1304");
result &= a != null;
}
catch (FileNotFoundException ex)
{
this.LogAction("Could not open the report. To view it, you need to have Crystal Reports v13.0.12 (32-bit only) installed.");
result = false;
}
catch
{
//Runtime is in GAC but something else prevents it from loading. (bad install?, etc)
result = false;
}
按预期工作。
我有一个工具,它从数据库中读取数据,修改它,然后将其显示在 crystal 报告中,该报告显示在单独的 window.
中该工具有时会被没有安装 Crystal 报告的人使用,所以我想显示特定的错误消息,告诉用户确切的操作(而不是现在的通用消息).
我打电话给 window 报告如下:
try
{
ReportWindow report = new ReportWindow(resultList);
report.Show();
}
catch (Exception ex)
{
this.LogAction("Could not open the report. To view it, you need to have Crystal Reports installed.", Notification.Error);
}
(为了这个问题简化了catch分支)
ReportWindow.xaml.cs
public ReportWindow(List<MeasureTestResult> measurement)
{
this._measurementList = measurement;
InitializeComponent();
}
ReportWindow.xaml
<Window x:Class="ResultFileViewer.Sources.ReportWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewer="clr-namespace:SAPBusinessObjects.WPF.Viewer;assembly=SAPBusinessObjects.WPF.Viewer">
<viewer:CrystalReportsViewer Name="CrystalReportsViewer1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Window>
ReportWindow
构造函数中的行 InitializeComponent();
抛出几个异常,例如 XamlParseException
或 InvalidCastException
。问题是,只有 XamlParseException
被捕获。其他异常仅由我的 DispatcherUnhandledException
属性 或我的 App.xaml.
这是有问题的,因为它要么意味着当e.Handled设置为false时整个应用程序被关闭,要么在用户关闭应用程序后仍然存在僵尸进程,当e.Handled是设置为真。
如何在调用报告 window 的 class 中捕获当前未处理的异常?
我尝试了 this solution,但也没有捕捉到 InvalidCastException
。
我已经放弃尝试捕获流氓异常,因为我没有成功。 相反,如果安装了 Crystal Reports,我会尝试预先检测。我基本上找到了两个选择:
- 检查注册表中的特定条目
- 如果需要的程序集存在,请检查全局程序集缓存 (GAC)
注册表检查有一个缺点,它只包含一个相当通用的名称而不是特定的版本条目(例如 HKEY_CURRENT_USER\Software\SAP BusinessObjects\Crystal Reports for .NET Framework 4.0
)。
此外,如果您事先安装了 Crystal Reports 并卸载了它,无论出于何种原因,注册表项都会保留,因此也无法可靠地检查是否安装了 Crystal Reports。
所以我进行了 GAC 检查,我是这样做的:
try
{
// 13.0.2000.0 is Crystal Reports for VS 2010
// the first assembly is the most important one, but it also gets deployed by the project itself
// because of this I picked two additional assemblies to check for
var a = System.Reflection.Assembly.Load("CrystalDecisions.CrystalReports.Engine, Version=13.0.2000.0, Culture=neutral,PublicKeyToken=692fbea5521e1304");
result = a != null;
a = System.Reflection.Assembly.Load("CrystalDecisions.CrystalReports.TemplateEngine, Version=13.0.2000.0, Culture=neutral,PublicKeyToken=692fbea5521e1304");
result &= a != null;
a = System.Reflection.Assembly.Load("CrystalDecisions.Windows.Forms, Version=13.0.2000.0, Culture=neutral,PublicKeyToken=692fbea5521e1304");
result &= a != null;
}
catch (FileNotFoundException ex)
{
this.LogAction("Could not open the report. To view it, you need to have Crystal Reports v13.0.12 (32-bit only) installed.");
result = false;
}
catch
{
//Runtime is in GAC but something else prevents it from loading. (bad install?, etc)
result = false;
}
按预期工作。