【问题标题】:Prevent "Send error report to Microsoft"阻止“向 Microsoft 发送错误报告”
【发布时间】:2009-01-23 15:45:41
【问题描述】:

我正在做一个相当大的项目,它不太可能包揽一切。我找到了通知我未处理异常的事件,但是我还没有找到以编程方式关闭 Windows 错误对话框的方法。理想情况下,如果有未处理的异常,我希望触发该事件,提供一个对话框告诉用户存在问题,然后优雅地关闭。有没有办法做到这一点?我意识到我可以将最高层包裹在 try catch 中,但我希望有一些更优雅的东西。

【问题讨论】:

    标签: c# error-handling


    【解决方案1】:

    这就是我们所做的。

    static void Main() {
        try
        {
            SubMain();
        }
        catch (Exception e)
        {
            HandleUnhandledException(e);
        }
    }
    
    private static void SubMain()
    {
        // Setup unhandled exception handlers
        AppDomain.CurrentDomain.UnhandledException += // CLR
           new UnhandledExceptionEventHandler(OnUnhandledException);
         Application.ThreadException += // Windows Forms
           new System.Threading.ThreadExceptionEventHandler(
               OnGuiUnhandledException);
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);
         Application.Run(new frmMain());
    }
    
    // CLR unhandled exception
    private static void OnUnhandledException(Object sender,
       UnhandledExceptionEventArgs e)
    {
        HandleUnhandledException(e.ExceptionObject);
    }
    
    // Windows Forms unhandled exception
    private static void OnGuiUnhandledException(Object sender,
       System.Threading.ThreadExceptionEventArgs e)
    {
        HandleUnhandledException(e.Exception);
    }
    

    【讨论】:

    • 为什么要同时实现 AppDomain.UnhandledException 将整个事物包装在 Try/Catch 块中?那是傻鹅。
    【解决方案2】:

    你有点回答了你自己的问题。防止错误对话框的最好方法是编写处理异常的代码,这样对话框就不会出现。我敢打赌这就是 Raymond Chen 的建议(如果我可以这么大胆的话)。

    【讨论】:

    • 我正在考虑全局尝试/捕获(如第一个答案)。我只是不确定这是否是最佳做法。我也不确定是否有更清洁的方法。
    【解决方案3】:

    http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

    虽然如果您将其作为商业项目发布,我鼓励您向 Microsoft 注册,以便实际获取发送到 MS 的故障转储和错误报告信息

    【讨论】:

      【解决方案4】:

      如果您使用的是 .NET 框架 2.0 或更高版本,并且工作线程中有未处理的异常,我相信您不走运。在 .NET 1.0 和 1.1 中,CLR 只是从主线程以外的线程吞下异常。但是,这在 .NET 2.0 中有所改变,其中线程上未处理的异常会导致应用程序关闭。

      您可以订阅 AppDomain.CurrentDomain.UnhandledException 以在发生此类未处理的异常时收到通知,但此时应用程序很可能正在关闭,您只是有机会在不可避免的情况发生之前做一些事情,例如记录在某个地方出现异常并显示用户友好的消息。 UnhandledExceptionEventArgs 有一个名为 IsTerminating 的只读属性,您可以检查该属性以查看应用程序是否正在终止。应用程序终止后,通常会弹出 Microsoft 错误报告对话框。

      虽然我不建议这样做,但有一种方法可以通过在应用程序配置文件中设置应用程序兼容性标志来恢复 CLR 1.0 和 1.1 的行为方式。

      这不应导致应用程序在出现未处理的异常时终止,并降低获得该错误报告对话框的可能性。

      我的建议是仅捕获您在代码中预期并能够处理的异常,并让其他异常冒泡。

      【讨论】:

      • 这取决于你如何管理你的工作线程。对于所有非长时间运行的作业,我首选的方法是使用 Delegate.BeginInvoke() 来使用 ThreadPool 线程来执行异步操作。如果你这样做,那么当你调用 EndInvoke() 时,线程将返回任何异常——你只需要确保为每个 BeginInvoke 调用 EndInvoke(不这样做会导致各种资源泄漏)。
      【解决方案5】:

      如果您的问题与 WinForms 应用程序有关,那么所选答案对您有用,但它并不完全优雅。

      .NET 为这个确切的场景提供了一个助手:

      Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException)
      AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException
      

      And here's the MSDN Documentation on the method

      【讨论】:

        【解决方案6】:

        您可以尝试使用 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AeDebug

        这个提示是 DrWatson 时代的 .. 可能有效,也可能无效。

        【讨论】:

        • 如果您要解决特定于应用程序的问题,请不要使用系统范围的设置
        • - 用户可能不喜欢您更改其设置的事实...- 您的应用程序可能没有对此注册表项的写入权限。
        猜你喜欢
        • 2010-11-14
        • 2011-07-24
        • 2016-05-28
        • 2019-10-09
        • 1970-01-01
        • 1970-01-01
        • 2018-09-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多