【问题标题】:How can I catch all exceptions, when I want to show a report and Crystal reports is not installed?当我想显示报表但未安装 Crystal 报表时,如何捕获所有异常?
【发布时间】:2016-01-29 11:45:39
【问题描述】:

我有一个工具,它可以从数据库中读取数据,对其进行修改,然后将其显示在一个水晶报表中,该报表显示在一个单独的窗口中。

该工具有时会被没有安装 Crystal Reports 的人使用,所以我想显示特定的错误消息,它告诉用户确切地做什么(而不是现在的一般消息)。

我用这样的报告调用窗口:

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(); 会引发几个异常,例如XamlParseExceptionInvalidCastException。问题是,只有XamlParseException 被捕获。其他异常仅由我的 App.xaml 的 DispatcherUnhandledException 属性处理。

这是有问题的,因为它要么意味着当 e.Handled 设置为 false 时整个应用程序被关闭,要么当 e.Handled 设置为 true 时用户关闭应用程序后仍然存在僵尸进程。

如何捕获类中当前未处理的异常,即调用报告窗口?

我试过this solution,但也没有赶上InvalidCastException

【问题讨论】:

    标签: c# wpf crystal-reports


    【解决方案1】:

    我已经放弃尝试捕获流氓异常,因为我没有成功。 相反,我尝试预先检测是否安装了 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;
    }
    

    按预期工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多