/*
* UnhandledExceptionDlg Class v. 1.1
*
* Copyright (c)2006 Vitaly Zayko
*
* History:
* September 26, 2006 - Added "ThreadException" handler, "SetUnhandledExceptionMode", OnShowErrorReport event
* and updated the Demo and code comments;
* August 29, 2006 - Updated information about Microsoft Windows Error Reporting service and its link;
* July 18, 2006 - Initial release.
*
*/
/* More info on MSDN:
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/exceptdotnet.asp
* http://msdn2.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx
* http://msdn2.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx
* http://msdn2.microsoft.com/en-us/library/system.windows.forms.unhandledexceptionmode.aspx
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using Inssider.Properties;
namespace Inssider
{
internal class SendExceptionClickEventArgs: System.EventArgs
{
public String UserDescription;
public bool SendExceptionDetails;
public Exception UnhandledException;
public bool RestartApp;
public SendExceptionClickEventArgs(bool SendDetailsArg, String Description, Exception ExceptionArg, bool RestartAppArg)
{
this.SendExceptionDetails = SendDetailsArg; // TRUE if user clicked on "Send Error Report" button and FALSE if on "Don't Send"
this.UserDescription = Description;
this.UnhandledException = ExceptionArg; // Used to store captured exception
this.RestartApp = RestartAppArg; // Contains user's request: should the App to be restarted or not
}
}
///
/// Class for catching unhandled exception with UI dialog.
///
class UnhandledExceptionDlg
{
private bool _dorestart = false;
///
/// Set to true if you want to restart your App after falure
///
public bool RestartApp
{
get { return _dorestart; }
set { _dorestart = value; }
}
public delegate void SendExceptionClickHandler(object sender, SendExceptionClickEventArgs args);
//public delegate void ShowErrorReportHandler(object sender, System.EventArgs args);
///
/// Occurs when user clicks on "Send Error report" button
///
public event SendExceptionClickHandler OnSendExceptionClick;
///
/// Occurs when user clicks on "click here" link lable to get data that will be send
///
public event SendExceptionClickHandler OnShowErrorReportClick;
public event SendExceptionClickHandler OnCopyToClipboardClick;
///
/// Default constructor
///
public UnhandledExceptionDlg()
{
InitializeApplicationHandlers();
}
public void InitializeApplicationHandlers() {
// Add the event handler for handling UI thread exceptions to the event:
Application.ThreadException += new ThreadExceptionEventHandler(ThreadExceptionFunction);
// 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(UnhandledExceptionFunction);
} // End
///
/// Handle the UI exceptions by showing a dialog box
///
///
///
private void ThreadExceptionFunction(Object sender, ThreadExceptionEventArgs e)
{
// Suppress the Dialog in Debug mode:
#if !DEBUG
ShowUnhandledExceptionDlg(e.Exception);
#endif
}
///
/// Handle the UI exceptions by showing a dialog box
///
/// Sender Object
/// Passing arguments: original exception etc.
private void UnhandledExceptionFunction(Object sender, UnhandledExceptionEventArgs args)
{
// Suppress the Dialog in Debug mode:
#if !DEBUG
ShowUnhandledExceptionDlg((Exception)args.ExceptionObject);
#endif
}
///
/// Raise Exception Dialog box for both UI and non-UI Unhandled Exceptions
///
/// Catched exception
public void ShowUnhandledExceptionDlg(Exception e)
{
Exception unhandledException = e;
if(unhandledException == null)
unhandledException = new Exception("Unknown unhandled Exception was occurred!");
UnhandledExDlgForm exDlgForm = new UnhandledExDlgForm();
try
{
string appName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
exDlgForm.Text = appName;
exDlgForm.labelTitle.Text = String.Format(exDlgForm.labelTitle.Text, appName);
// Do not show link label if OnShowErrorReport is not handled
exDlgForm.labelLinkTitle.Visible = (OnShowErrorReportClick != null);
exDlgForm.linkLabelData.Visible = (OnShowErrorReportClick != null);
// Disable the Button if OnSendExceptionClick event is not handled
exDlgForm.buttonSend.Enabled = (OnSendExceptionClick != null);
// Handle clicks on report link label
exDlgForm.linkLabelData.LinkClicked += delegate(object o, LinkLabelLinkClickedEventArgs ev)
{
if(OnShowErrorReportClick != null)
{
SendExceptionClickEventArgs ar = new SendExceptionClickEventArgs(true, "", unhandledException, _dorestart);
OnShowErrorReportClick(this, ar);
}
};
exDlgForm.buttonCopy.Click += delegate(object o, EventArgs ev)
{
if (OnCopyToClipboardClick != null)
{
SendExceptionClickEventArgs ar = new SendExceptionClickEventArgs(true, exDlgForm.UserDescription, unhandledException, _dorestart);
OnCopyToClipboardClick(this, ar);
}
exDlgForm.buttonCopy.Enabled = false;
};
// Show the Dialog box:
bool sendDetails = (exDlgForm.ShowDialog() == System.Windows.Forms.DialogResult.Yes);
if(OnSendExceptionClick != null)
{
SendExceptionClickEventArgs ar = new SendExceptionClickEventArgs(sendDetails, exDlgForm.UserDescription, unhandledException, _dorestart);
OnSendExceptionClick(this, ar);
}
}
finally
{
exDlgForm.Dispose();
}
}
}
}