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()
Related
So i am making a program for school, the section i am working on currently i have an if statement set up and when the if is false it will throw and exception, I have a catch set up in the main window but the exception is never caught just thrown, which stops the program. I understand i need the catch in the main window because that is the only location i can have a messagebox.show. But how do i pass the exception throughout multiple classes?
Use something like this:
AppDomain.CurrentDomain.UnhandledException
+= new UnhandledExceptionEventHandler(ErrorHandler.HandleException);
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.
In my c# win-forms application, I have changed the following line in Main()
Application.Run(new MainMenuForm());
as
MainMenuForm mainMenuForm = new MainMenuForm();
mainMenuForm.ShowDialog();
Is it the cause of the above error?
Stack trace shows following method causes the exception
System.Windows.Forms.UnsafeNativeMethods.CallWindowProc()
Any help appreciated
Thanks
You need to use Application.Run on some form because it starts message loop on your main gui thread for WinProc.
http://msdn.microsoft.com/en-us/library/system.windows.forms.application.run.aspx
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!
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.