禁用“Foo遇到问题需要关闭”窗口。

7

除了WerAddExcludedApplication(在Windows XP中无法使用)之外,是否有其他方法可以禁用窗口“应用程序遇到问题并需要关闭”在我的应用程序崩溃时出现?

alt text

(图片来源于Bil Simser的博客

我需要它在Windows XP中运行。


10
保持你的应用程序不崩溃。 - John Gietzen
4个回答

7

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

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应用程序中怎么办?比如说...在控制台应用程序中,我没有使用Application类? - Krzysztof Kozmic

2

谢谢,但在这种情况下,这真的不是一个解决方案。我需要特别要求的东西——当应用程序崩溃时重新启动应用程序而不弹出对话框。 - Krzysztof Kozmic

1

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


这些是事件,因此您可以采取行动,而不是进行太多处理,但这并不重要。一旦应用程序被损坏,您可能没有其他选择,只能关闭应用程序,那么接下来该怎么办呢? - Krzysztof Kozmic
再加上它也不会起作用 - 即使您订阅了事件,窗口仍然会显示出来。 - Krzysztof Kozmic
哦,如果你到了这个阶段,你肯定应该终止应用程序,但我认为展示一个自定义的崩溃对话框并没有什么大问题。至于你的第二条评论,我只能说在这里它是有效的。 - Simon
@Krzysztof 如果你在事件处理程序中调用AppDomain.FailFast()(我可能没有完全记住类名),它不会起作用。但是,再次利用WER报告! - Ana Betts

1

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接