How to track window form crashing ? Like any event is called or anything else is called or we can track that window form is crashed ? Like dispose is called window form is crashed. But anything else which is happened so we can track out crashing of window form ?
Like problem is I have one window application on that there is tutorial balloon on the main form which moves for each control on the main form and describes the application functionality by indicating control on the main form one by one. And each time balloon moves balloon is disposes and new balloon form is created.
Now I want to insert the step number in the database when that balloon was crashed. I cannot understand what should I do ? What is happened when that balloon window(window form) is crashed ? There is a dispose event which is occurred but it is happened each time balloon creates so is there any thing else to track crashing ?
EDIT: Sorry to all, I forgot to specify that it is with .net framework 2.0.
Use this: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx
If any undhandled exception occurs in a forms thread, it will get here. If it's null, you get the usual dialog (undhandled exception occurred, you can continue or close, and see the stack trace).
This is an excerpt from a small Windows Forms 2.0 program of mine:
[STAThread]
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException +=
applicationThreadException;
// Set the unhandled exception mode to force all Windows Forms
// errors to go through our handler.
Application.SetUnhandledExceptionMode(
UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException +=
currentDomainUnhandledException;
...
}
With the two handlers
private static void currentDomainUnhandledException(
object sender,
UnhandledExceptionEventArgs e)
{
handleException(e.ExceptionObject as Exception);
}
and
private static void applicationThreadException(
object sender,
ThreadExceptionEventArgs e)
{
handleException(e.Exception);
}
The actual function to handle the exceptions does in my example:
private static void handleException(
Exception exception)
{
LogCentral.Current.LogError(
#"Exception occurred.",
exception);
if (ErrorForm.IsErrorFormShowing)
{
LogCentral.Current.LogInfo(
#"Error form already showing, not showing again.",
exception);
}
else
{
using (var form = new ErrorForm(exception))
{
var result = form.ShowDialog();
if (result == DialogResult.Abort)
{
Application.Exit();
}
}
}
}
I.e. it logs the error via log4net and then displays an error form to show the user further information (exception message) and allow to quit the application.
In your Program.cs file, place a try/catch block inside the Main() function. The idea is to have the Application.Run(yourformhere) inside such a block. Then inside the catch you can probably manage to save some state (like the step at which the balloon crashed the form) in the DB. Good Luck!
Related
In winforms, if an unhandled exception is encountered, a dialogue pops up alerting you that an exception occurred. This has buttons to continue execution or quit the application. What I was wondering is what state the app continues from if you select the continue button. My instinct would have been that it operated like in a debugger, continuing on the next statement after the exception, but this doesn't seem to be the case. To demonstrate this, I made a winforms app with a TextBox textBox1 and a button button1 with the following functions:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void button1_Click(object Sender, EventArgs e) {
textBox1.Text = "Line before exception";
throw_Exception();
textBox1.Text = "Line after exception";
}
private void throw_Exception() => throw new Exception();
}
With this you see "Line before exception", then the exception dialogue (yay), but even if you hit continue, you do not reach "Line after exception". Obviously this is a silly example, but I am still unclear on what the continue button is actually doing. If the exception was thrown at the bottom of a large hierarchy does execution of everything up to the UI level stop? Does garbage collection run on any objects created before the exception? What if the exception is thrown on one thread of a multithreaded program?
Disclaimer: Yes, I know that there shouldn't be unhandled exceptions, and I certainly should not be throwing a general System.Exception. I am just asking how the continue operation works under the hood and how to determine what state a system is in if the continue button is pressed.
I created a form to handle login to my app, and I'm trying to make the application exit if the login form is closed without logging in (for example, Alt-F4-ing). To do this I call Close() on the main form when DialogResult.OK is not returned but get an exception thrown in Main by Application.Run.
This is for a project I'm working on. Have tried searching for answers and found some saying to call Application.Exit() in the main form but that just makes my form reappear.
The main form's constructor:
public Menu()
{
InitializeComponent();
Form login = new Login_Forms.Login();
Hide();
if (login.ShowDialog(this) != DialogResult.OK)
Close();
else
Show();
}
Main():
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Menu()); // This line throws System.ObjectDisposedException
}
The program itself works but the exception thrown here is driving me mad. I'm searching for a way to close the main form properly so that an exception won't be thrown in Main.
You are calling Close() in constructor, before the object is fully created. Move your code to Form.Load()
I started a blank WPF application (shown below) to implement HockeyApp crash reporting. When the program starts, a window popups up with a single button for the user to press. When the user clicks it the handler attempts to divide by zero and crashes the app. I was receiving crash reports and everything was running smoothly UNTIL I mimicked our bigger system's error catching method, which was to use the DispatcherUnhandledException Event Handler to catch "uncaught" exceptions and then call System.Environment.Exit(0) to gracefully end anything in the background. Now the HockeyApp api isn't sending crash reports. I'm wondering if catching the exceptions at a higher level makes HockeyApp think "Oh, they got things under control" and won't register a "crash."
I'm currently talking to the HockeyApp support staff about this, but I'm wondering if anyone else has had this problem. Should I take out the Exit(0) line, or is there a better practice for exiting an app when we have an uncaught exception? I've tried changing the error code from 0 to 574 (ERROR_UNHANDLED_EXCEPTION) with no result. I don't believe there's any data that we need to save, other than what the HockeyApp api already has.
App class:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
RegisterHockeyAppCrashReporting();
Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
}
private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
System.Environment.Exit(0);
}
private async void RegisterHockeyAppCrashReporting()
{
HockeyClient.Current.Configure(AppConstants.APP_ID)
.SetContactInfo(AppConstants.USER_NAME, AppConstants.USER_EMAIL);
await HockeyClient.Current.SendCrashesAsync(true);
}
}
MainWindow class:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var zero = 0;
var number = 1;
var crash = number / zero;
}
}
Environement.Exit terminates your application immediately. So, I guess, there's nothing strange in the fact that Hockey does not do anything.
Exit terminates an application immediately, even if other threads are
running. If the return statement is called in the application entry
point, it causes an application to terminate only after all foreground
threads have terminated.
If Exit is called from a try or catch block, the code in any finally
block does not execute. If the return statement is used, the code in
the finally block does execute.
Best practices tend to be opinion based and situation dependent. We, for example, log stack trace on unhandled exceptions and then call Environement.FailFast in our UWP app (we do not use Hockey apps though). Our logic is simple - our logger facility is probably alive but we're not so sure about the rest of the app. If even the logger facility is not functional than we won't be able to do anything anyway. Imho Exit and FailFast are the last steps that should only be used when you have no hope of restoring some valid state.
Currently, when there is an unhandled error in one of the forms in my Windows Forms program, a dialog pops up with lots of details which are irrelevant and confusing to the end user.
I would like to replace that dialog with a more user-friendly dialog (and use a Tabbed interface to hide but make available technical details) whenever an unhandled error occurs in one of my forms.
Is there a way to replace this default dialog with a custom one?
My application is an MDI one, so if an error occurs in a form, I would like to just close out that form, show the error in a friendly way and allow them to work with other windows in the application (unless its a critical error).
A couple of ways spring to mind. Easiest one is to catch all unhandled exceptions by listening to the Application.ThreadException event
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(new Form1());
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message);
}
However that would simply stop the crashing and not close the mdi form. If you stop the sending thread, it would stop the mdi form altogether (it's easier outside mdi, then the forms can run in separate threads which can be initiated sandboxed).
What I normally do is run all code sandboxed. Normally encapsulated inside an action object, but i could be a simple procedure e.g.
public static bool Run(Action a)
{
try
{
a();
return true;
}
catch(Exception ex)
{
//custom error handling here
return false;
}
}
example call:
private void button1_Click(object sender, EventArgs e)
{
Run( ()=>throw new Exception());
}
Running in a standard method has the added benefit of being able to control things as a wait cursor or logging. If it wasn't an mdi environment, there would be some alternatives, but hope this one is doable.
I have been looking at the Windows API Code Pack 1.1 and have seen a Error sample and would like to integrate it into my Application, the main idea would be for it to show if any error in the application happens, well not any but some that I choose.
How can I program this?
I am using WPF
Thanks
In the constructor of your App class add:
DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
then add a method to the App class similar to the following:
void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
e.Handled = true;
if (MessageBox.Show("An unexpected error has occurred. You should exit this program as soon as possible.\n\n" +
"Exit the program now?\n\nError details:\n" + e.Exception.Message,
"Unexpected error", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
Shutdown();
}
You can have an catch block at the top-level of your program that will display the form with relevant error details. Or you can trap unhandled exceptions using the Application.UnhandledException (assuming you are using winforms), Application.ThreadException and AppDomain.UnhandledException.
If you want a message window to show up when any exception occurs, handled or not, then you will either have to explicitly write code in each catch block to show the form, or use something like PostSharp to weave in code that shows the form whenever an exception is thrown.
The following will catch all exceptions and display them in a messagebox:
[STAThread]
public static void Main()
{
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(new Form1());
}
private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
// work with exception
MessageBox.Show(e.Exception.Message);
}
Do note that if you're heavy into threading, you might want to test its behaviour with a thread-heavy application.
More information here.