I wrote this little program to demonstrate the point of the question:
using System;
using System.IO;
using System.Threading;
class Program
{
static void Main(string[] args)
{
using (var disp = new MyDisp())
{
using (var ewhLocalExit = new EventWaitHandle(false, EventResetMode.ManualReset))
{
Console.WriteLine("Enter Ctrl+C to terminate the app.");
Console.CancelKeyPress += (_, e) =>
{
e.Cancel = true;
ewhLocalExit.Set();
};
ewhLocalExit.WaitOne();
}
}
File.AppendAllText("Log.txt", "Terminated.\n");
}
}
class MyDisp : IDisposable
{
public MyDisp()
{
File.AppendAllText("Log.txt", "Started.\n");
}
public void Dispose()
{
File.AppendAllText("Log.txt", "Disposed.\n");
}
}
When I run it and press Ctrl+C, I see "Started.Disposed.Terminated." in Log.txt
When I run it and close it with the mouse, I see only "Started."
How do I make exit gracefully, so that I at least could see "Disposed." ?
You can use DLLImport to import SetConsoleControlHandler and use it to register an event handler for the closed event (and others), here's an example snippet that shows it working (it will write closed in Log.txt whem you click the X to close the console):
class Program
{
[DllImport("Kernel32")]
public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);
// A delegate type to be used as the handler routine
// for SetConsoleCtrlHandler.
public delegate bool HandlerRoutine(CtrlTypes CtrlType);
// An enumerated type for the control messages
// sent to the handler routine.
public enum CtrlTypes
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT,
CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT
}
private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
{
if (ctrlType == CtrlTypes.CTRL_CLOSE_EVENT)
File.AppendAllText(@"Log.txt", "closed");
return true;
}
private static void Main(string[] args)
{
SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true);
Console.WriteLine("Close me");
Console.ReadLine();
}
}
Source
When you close your console app with the mouse by clicking the X
button you are asking to have the process killed.
The Wi32 api has a SetConsoleControlHandler that allows you to specify a handler for when various things happen. If the handler is called with CTRL_CLOSE_EVENT then you know that someone is trying to kill your application.
There's an example of how to use this API here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With