Ответ 1
Вам нужно подключиться к консольному событию выхода, а не к вашему процессу.
http://geekswithblogs.net/mrnat/archive/2004/09/23/11594.aspx
Я ищу способ вызвать кусок кода, когда консольное приложение закрыто вручную (пользователи закрывают окно). Пробовал с помощью:
AppDomain.CurrentDomain.ProcessExit +=
new EventHandler(CurrentDomain_ProcessExit);
но указанное выше не работает, если оно закрыто вручную.
Есть ли способ использовать для этого .Net-вызов или мне нужно импортировать dll ядра и сделать это таким образом?
Вам нужно подключиться к консольному событию выхода, а не к вашему процессу.
http://geekswithblogs.net/mrnat/archive/2004/09/23/11594.aspx
Этот код работает, чтобы уловить пользователя, закрывающего окно консоли:
using System;
using System.Runtime.InteropServices;
class Program {
static void Main(string[] args) {
handler = new ConsoleEventDelegate(ConsoleEventCallback);
SetConsoleCtrlHandler(handler, true);
Console.ReadLine();
}
static bool ConsoleEventCallback(int eventType) {
if (eventType == 2) {
Console.WriteLine("Console window closing, death imminent");
}
return false;
}
static ConsoleEventDelegate handler; // Keeps it from getting garbage collected
// Pinvoke
private delegate bool ConsoleEventDelegate(int eventType);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetConsoleCtrlHandler(ConsoleEventDelegate callback, bool add);
}
Остерегайтесь ограничений. Вы должны быстро ответить на это уведомление, у вас есть 5 секунд, чтобы выполнить задачу. Возьмите больше времени, и Windows будет убивать ваш код бесцеремонно. И ваш метод называется асинхронно на рабочем потоке, состояние программы совершенно непредсказуемо, поэтому, вероятно, потребуется блокировка. Убедитесь, что прерывание не может вызвать проблемы. Например, при сохранении состояния в файл сначала убедитесь, что вы сохранили его во временном файле и используете File.Replace().