Вот моя попытка решить эту проблему. Диспетчер задач все еще может закрыть приложение. Но я думал попытаться определить, когда оно закрывается, а затем снова запустить его. Однако я не реализовал эту часть.
Следующая программа обнаружит CTRL-C && CTRL-BREAK и продолжит работу.
РЕДАКТИРОВАТЬ: Удалена кнопка "X"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace DoNotCloseMe
{
class Program
{
const string _title = "DO NOT CLOSE - Important Program";
static void Main(string[] args)
{
Console.Title = _title;
IntPtr hMenu = Process.GetCurrentProcess().MainWindowHandle;
IntPtr hSystemMenu = GetSystemMenu(hMenu, false);
EnableMenuItem(hSystemMenu, SC_CLOSE, MF_GRAYED);
RemoveMenu(hSystemMenu, SC_CLOSE, MF_BYCOMMAND);
WriteConsoleHeader();
//This function only seems to be called once.
//After calling MainLoop() below, CTRL-C && CTRL-BREAK cause Console.ReadLine() to return NULL
Console.CancelKeyPress += (sender, e) =>
{
Console.WriteLine("Clean-up code invoked in CancelKeyPress handler.");
Console.WriteLine("Key Pressed: {0}", e.SpecialKey.ToString());
System.Threading.Thread.Sleep(1000);
MainLoop();
// The application terminates directly after executing this delegate.
};
MainLoop();
}
private static void MainLoop()
{
while (true)
{
WriteConsoleHeader();
string x = Console.ReadLine();
if (!String.IsNullOrEmpty(x))
{
switch (x.ToUpperInvariant())
{
case "EXIT":
case "QUIT":
System.Environment.Exit(0);
break;
default:
StartLongRunningTaskOnSeparateThread(x);
break;
}
}
}
}
private static void StartLongRunningTaskOnSeparateThread(string command)
{
var bg = new System.ComponentModel.BackgroundWorker();
bg.WorkerReportsProgress = false;
bg.WorkerSupportsCancellation = false;
bg.DoWork += (sender, args) =>
{
var sleepTime = (new Random()).Next(5000);
System.Threading.Thread.Sleep(sleepTime);
};
bg.RunWorkerCompleted += (sender, args) =>
{
Console.WriteLine("Commmand Complete: {0}", command);
};
bg.RunWorkerAsync();
}
private static void WriteConsoleHeader()
{
Console.Clear();
Console.WriteLine(new string('*', Console.WindowWidth - 1));
Console.WriteLine(_title);
Console.WriteLine(new string('*', Console.WindowWidth - 1));
Console.WriteLine("Please do not close this program.");
Console.WriteLine("It is maintaining the space/time continuum.");
Console.WriteLine("If you close it, Q will not be happy and you will be assimilated.");
Console.WriteLine(new string('*', Console.WindowWidth - 1));
Console.WriteLine("Development Mode: Use \"EXIT\" or \"QUIT\" to exit application.");
Console.WriteLine(new string('*', Console.WindowWidth - 1));
}
#region "Unmanaged"
[DllImport("user32.dll")]
static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
[DllImport("user32.dll")]
static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
static extern IntPtr RemoveMenu(IntPtr hMenu, uint nPosition, uint wFlags);
internal const uint SC_CLOSE = 0xF060;
internal const uint MF_GRAYED = 0x00000001;
internal const uint MF_BYCOMMAND = 0x00000000;
#endregion
}
}