I have an app that doesn't show any forms most of the time, and I needed it to close by itself when a user was shutting down the system.
So I created a question, and the answer there, SystemEvents.SessionEnding, seemed to work.
At first.
Here is my Program.Main()
method:
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
#region Pre-launch stuff
// Are we upgrading from an older version? We need to grab our old settings!
if (Properties.Settings.Default.UpgradeSettings)
{
Properties.Settings.Default.Upgrade();
Properties.Settings.Default.UpgradeSettings = false;
Properties.Settings.Default.Save();
}
// Visual styles
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
#if !DEBUG
// Add the event handler for handling UI thread exceptions to the event.
Application.ThreadException += new ThreadExceptionEventHandler(ErrorHandling.Application_ThreadException);
// 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(ErrorHandling.CurrentDomain_UnhandledException);
#endif
// Since we have no forms open we need to watch for the shutdown event; otherwise we're blocking it
SystemEvents.SessionEnding += new SessionEndingEventHandler(SystemEvents_SessionEnding);
// ...
// ...
// ...
Application.Run();
}
The method SystemEvents_SessionEnding
runs a method calling Exit()
, which in turn runs:
public static void Exit()
{
MessageBox.Show("test");
try
{
IconHandler.SuperNotifyIcon.Dispose();
}
finally
{
Application.Exit();
}
}
And yet, my app blocks shutdown at times. And the message box that I added there doesn't show up.
I can't figure out how such a simple, simple path of execution could fail. But it does, and it's a major irritant for both me and my app's users.
Any ideas? Thoughts to throw around?
EDIT:
Per corvuscorax's answer, I've tried adding a form, but it's acted weird - at first, I had this in the form's code:
ShowInTaskbar = false;
WindowState = FormWindowState.Minimized;
Shown += (sender, e) => Hide();
And modified the Program.Exit()
method to close that form, which would run the disposal code as well in the FormClosing
event.
It turned out disabling ShowInTaskbar
stopped the form from receiving a HWND_BROADCAST
message. I've commented out that line now, but even so, I found that shutdown blocking was occurring. Once I clicked a button I made to show the form and tried to shut down again, it completed smoothly.