For some reason, I treat a .NET 8 webapi as an application on Windows, and I publish it using a self-contained method and execute it.
But I want to know how to capture the event when the user closes the program via the icon on the Windows toolbar or the window's upper-right corner.
Currently, I'm trying to use app.Lifetime.ApplicationStopping
, but it seems to only capture the termination triggered by pressing Ctrl+C
in the console, and cannot detect the closure triggered by clicking the icon or the upper right corner of the window.
In fact, my ultimate goal is to perform some actions when a particular service ends. It's another .NET 8 DLL, but its destructors don't seem to be triggered either.
So if there's a better way to achieve this, please suggest it. Thanks.
Update:
When I use AppDomain.CurrentDomain.ProcessExit
, I can catch it. However, at this point, the object has become null, making it difficult to manipulate.
You could check out this snippet, but it would be better to use a Windows service and detect StopAsync
class Program
{
// https://learn.microsoft.com/en-us/windows/console/setconsolectrlhandler?WT.mc_id=DT-MVP-5003978
[DllImport("Kernel32")]
private static extern bool SetConsoleCtrlHandler(SetConsoleCtrlEventHandler handler, bool add);
// https://learn.microsoft.com/en-us/windows/console/handlerroutine?WT.mc_id=DT-MVP-5003978
private delegate bool SetConsoleCtrlEventHandler(CtrlType sig);
private enum CtrlType
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT = 1,
CTRL_CLOSE_EVENT = 2,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT = 6
}
static void Main(string[] args)
{
// Register the handler
SetConsoleCtrlHandler(Handler, true);
// Wait for the event
while (true)
{
Thread.Sleep(50);
}
}
private static bool Handler(CtrlType signal)
{
switch (signal)
{
case CtrlType.CTRL_BREAK_EVENT:
case CtrlType.CTRL_C_EVENT:
case CtrlType.CTRL_LOGOFF_EVENT:
case CtrlType.CTRL_SHUTDOWN_EVENT:
case CtrlType.CTRL_CLOSE_EVENT:
Console.WriteLine("Closing");
// TODO Cleanup resources
Environment.Exit(0);
return false;
default:
return false;
}
}
}