gpt4 book ai didi

.net - 阻止 .net 控制台应用程序被关闭

转载 作者:行者123 更新时间:2023-12-04 00:23:56 25 4
gpt4 key购买 nike

有没有办法阻止 .NET 控制台应用程序被关闭?我有一个遵循这种模式的应用程序:

while (true)
{
string x = Console.ReadLine();
StartLongRunningTaskOnSeparateThread(x);
}

问题是可以关闭控制台窗口(从而切断长时间运行的任务)。控制台应用程序是否有等效的 Forms.OnClosing 事件?

编辑 - 我不是想创造一些不可能杀死的东西,只是可能给出一个警告信息,例如“嘿,我还没有完成。你确定要关闭我吗?”

EDIT2 - 防止通过“x”按钮过早退出比阻止 Ctrl-C 更重要(我使用了 Console.TreatControlCAsInput = true; )。为此,假设任何启动任务管理器的人都想杀死该程序,以至于他们理应如此。并且最终用户宁愿看到警告也不愿意外取消他们长时间运行的任务。

最佳答案

这是我解决这个问题的尝试。任务管理器仍然可以关闭应用程序。但是,我的想法是尝试检测它何时关闭,然后重新启动它。但是,我没有实现那部分。

以下程序将检测 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
}
}

关于.net - 阻止 .net 控制台应用程序被关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/877839/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com