【问题标题】:Disable "Foo has encountered a problem and needs to close" window禁用“Foo 遇到问题需要关闭”窗口
【发布时间】:2010-12-13 10:23:09
【问题描述】:

当我的应用程序崩溃时,是否有办法(WerAddExcludedApplication 除外,它在 Windows XP 中不起作用)来禁用“应用程序遇到问题并需要关闭”窗口?

(图片取自 Bil Simser'blog

我需要这个才能在 Windows XP 中工作。

【问题讨论】:

  • 是的,防止您的应用崩溃。

标签: .net windows exception


【解决方案1】:

这将起作用,允许您显示自己的自定义对话框:

Application.ThreadException += new ThreadExceptionEventHandler(ThreadExceptionFunction);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionFunction);

这是来自MSDN的完整示例:

Thread newThread = null;

// Starts the application. 
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
public static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

    // Set the unhandled exception mode to force all Windows Forms errors to go through
    // our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException +=
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    // Runs the application.
    Application.Run(new ErrorHandlerForm());
}

// Programs the button to throw an exception when clicked.
private void button1_Click(object sender, System.EventArgs e)
{
    throw new ArgumentException("The parameter was invalid");
}

// Start a new thread, separate from Windows Forms, that will throw an exception.
private void button2_Click(object sender, System.EventArgs e)
{
    ThreadStart newThreadStart = new ThreadStart(newThread_Execute);
    newThread = new Thread(newThreadStart);
    newThread.Start();
}

// The thread we start up to demonstrate non-UI exception handling. 
void newThread_Execute()
{
    throw new Exception("The method or operation is not implemented.");
}

// Handle the UI exceptions by showing a dialog box, and asking the user whether
// or not they wish to abort execution.
private static void Form1_UIThreadException(object sender, ThreadExceptionEventArgs t)
{
    DialogResult result = DialogResult.Cancel;
    try
    {
        result = ShowThreadExceptionDialog("Windows Forms Error", t.Exception);
    }
    catch
    {
        try
        {
            MessageBox.Show("Fatal Windows Forms Error",
                "Fatal Windows Forms Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
        }
        finally
        {
            Application.Exit();
        }
    }

    // Exits the program when the user clicks Abort.
    if (result == DialogResult.Abort)
        Application.Exit();
}

// Handle the UI exceptions by showing a dialog box, and asking the user whether
// or not they wish to abort execution.
// NOTE: This exception cannot be kept from terminating the application - it can only 
// log the event, and inform the user about it. 
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    try
    {
        Exception ex = (Exception)e.ExceptionObject;
        string errorMsg = "An application error occurred. Please contact the adminstrator " +
            "with the following information:\n\n";

        // Since we can't prevent the app from terminating, log this to the event log.
        if (!EventLog.SourceExists("ThreadException"))
        {
            EventLog.CreateEventSource("ThreadException", "Application");
        }

        // Create an EventLog instance and assign its source.
        EventLog myLog = new EventLog();
        myLog.Source = "ThreadException";
        myLog.WriteEntry(errorMsg + ex.Message + "\n\nStack Trace:\n" + ex.StackTrace);
    }
    catch (Exception exc)
    {
        try
        {
            MessageBox.Show("Fatal Non-UI Error",
                "Fatal Non-UI Error. Could not write the error to the event log. Reason: "
                + exc.Message, MessageBoxButtons.OK, MessageBoxIcon.Stop);
        }
        finally
        {
            Application.Exit();
        }
    }
}

// Creates the error message and displays it.
private static DialogResult ShowThreadExceptionDialog(string title, Exception e)
{
    string errorMsg = "An application error occurred. Please contact the adminstrator " +
        "with the following information:\n\n";
    errorMsg = errorMsg + e.Message + "\n\nStack Trace:\n" + e.StackTrace;
    return MessageBox.Show(errorMsg, title, MessageBoxButtons.AbortRetryIgnore,
        MessageBoxIcon.Stop);
}

【讨论】:

  • 如果我不在 WinForms 应用程序中怎么办?但是说...控制台应用程序,我不使用应用程序类?
【解决方案2】:

我的建议是,不要禁用此对话框,而是向 Microsoft 注册,以便您可以看到我们捕获的错误报告!这样,您可以使用此对话框,而不是试图抑制它。

http://msdn.microsoft.com/en-us/isv/bb190483.aspx

【讨论】:

  • 谢谢,但在这种情况下,它真的不是解决方案。我特别需要我所问的 - 能够在应用程序崩溃时重新启动而不弹出该对话框。
【解决方案3】:

您需要处理Application.ThreadExceptionAppDomain.CurrentDomain.UnhandledException 事件。

【讨论】:

  • 这些是事件,所以你可以对它们采取行动,而不是真正做太多的处理,但这不是重点。一旦应用程序损坏,您可能没有其他选择来关闭应用程序,然后该怎么办?
  • 另外它无论如何都不会起作用 - 即使您订阅了该事件,窗口仍然会显示
  • 哦,如果你到了这个阶段,你肯定应该终止应用程序,但我认为呈现自定义崩溃对话框没有什么大问题。至于您的第二条评论,我只能说它在这里有效。
  • @Krzysztof 如果您在事件处理程序中调用 AppDomain.FailFast() (我可能不记得类 100% 正确),它不会。但同样,使用 WER 报告对您有利!
【解决方案4】:

这不是编程解决方案,但您可以通过编辑 Windows 错误报告设置来做到这一点。

  1. 打开控制面板
  2. 打开系统,系统属性对话框将打开
  3. 转到高级选项卡
  4. 单击错误报告,将打开错误报告对话框
  5. 如果您希望在单个应用程序上禁用它,请单击“选择程序”按钮,将打开一个对话框
  6. 单击(第二个)添加按钮,将您的应用程序添加到“不报告这些程序的错误”列表。
  7. 确认所有三个对话框...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    • 2011-10-03
    • 1970-01-01
    相关资源
    最近更新 更多