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

2023-11-22

有什么方法可以阻止 .NET 控制台应用程序关闭吗?我有一个遵循以下模式的应用程序:

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

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

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

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


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

以下程序将检测 CTRL-C && CTRL-BREAK 并将继续运行。

EDIT:删除了“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
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

阻止 .net 控制台应用程序关闭 的相关文章

随机推荐

  • Hadoop 流 - 从减速器输出中删除尾随选项卡

    我有一个 hadoop 流作业 其输出不包含键 值对 您可以将其视为仅值对或仅键对 我的流式减速器 一个 php 脚本 正在输出由换行符分隔的记录 Hadoop 流处理将此视为没有值的键 并在换行符之前插入一个制表符 这个额外的选项卡是不需
  • 获得 Cassandra Writes 背压的最佳方法是什么?

    我有一项服务以我控制的速率消耗队列中的消息 我做了一些处理 然后尝试通过 Datastax Java 客户端写入 Cassandra 集群 我已经设置了我的 Cassandra 集群maxRequestsPerConnection and
  • 使用友元函数进行前向声明:不完整类型的使用无效

    include
  • 如果我不需要用户访问令牌,如何使用请求从 Python 连接到 Facebook Graph API?

    我正在尝试找到如何使用我最喜欢的 Facebook Graph API 的最简单方法Requests图书馆 问题是 我发现的所有例子都是关于获取用户访问令牌 关于重定向和用户交互 我所需要的只是应用程序访问令牌 我不处理任何非公开数据 因此
  • std::list 应该被弃用吗?

    根据 Bjarne Stroustrup 的说法slides从他的2012 年本土化主题演讲 在a中插入和删除std list在现代硬件上效率非常低 矢量节拍列表大量用于插入和删除 如果这确实是真的 那么还剩下哪些用例std list 那不
  • DataTrigger 不会更改 Text 属性

    我正在尝试在样式上使用数据触发器来更改属性 符合 最小 完整且可验证的示例 要求 要重现 首先在 Visual Studio 中创建一个 WPF 应用程序 在 App xaml cs 内 using System ComponentMode
  • 405(方法不允许)并被 CORS 策略阻止

    我有 Asp Net Core 3 WebApi 项目 其 UI 基于客户端的 Angular 7 2 1 当使用 Postman 或仅使用 URL 时 我可以使用 GET 和 POST 而不会出现任何特定错误 当通过 Angular Ch
  • 在合并列中将两个数据帧与 pd.NA 合并会产生“TypeError:NA 的布尔值不明确”

    使用 Pandas 1 0 1 如果以下情况我无法合并 df df merge df2 on some column yields File home torstein code fintechdb Sheets sheets gild p
  • 为什么不在单元测试中访问数据库?

    我在博客中读到 单元测试运行时不应访问数据库 我理解这个理论 但是说我有复杂的存储过程 这是业务领域操作的一部分 我想为与业务操作相关的代码编写一组单元测试 但是如果我模拟数据库 我会感觉我没有 真正 测试属于操作的所有部分 例如 有人可能
  • 从另一个应用程序以编程方式提交并终止 Spark 应用程序

    我想知道是否可以submit monitor kill从另一个服务激发应用程序 我的要求如下 我写了一个服务 parse用户命令 翻译他们变成可以理解的论据 to an 已经准备好的 Spark SQL 应用程序 使用以下命令将应用程序连同
  • Crockford 原型继承的小缺点

    只是在 JS 中尝试不同的继承技术 并发现 Crockford 的原型继承模式有些令人不安的地方 function object o function F F prototype o return new F var C P foo bar
  • 如何为 Python 迭代器编写分页器?

    我正在寻找一种 翻阅 Python 迭代器的方法 也就是说 我想包装给定的迭代器iter and 页面大小使用另一个迭代器 它将从 iter 返回项目作为一系列 页面 每个页面本身就是一个迭代器 最多可达页面大小迭代 我翻阅了迭代工具我看到
  • 在“选择前 n”查询中返回未锁定的行

    我需要有一个 MsSql 数据库表和另外 8 个 相同的 进程并行访问同一个表 选择前 n 行 处理这 n 行 并更新这些行的列 问题是我只需要选择并处理每一行一次 这意味着 如果一个进程访问数据库并选择了前 n 行 那么当第二个进程到来时
  • 如何使用 Python 验证特定的日期和时间格式

    我正在编写一个程序来验证 XML 文件的部分内容 我想验证的要点之一是日期时间格式 我已经在论坛上阅读了有关使用的信息time strptime 但这些例子不太适合我 而且有点超出了我的专业知识 任何人都知道我如何验证以下内容 这是日期和时
  • Git : 错误:RPC 失败; curl 92 HTTP/2 流 0 未完全关闭:PROTOCOL_ERROR (err 1)

    请不要在未阅读完整问题的情况下将其标记为重复项 当我尝试将代码推送到我们的存储库时 出现以下错误 我尝试在网上搜索这个问题 发现了惊人的资源 但没有确切的解决方案 有很多类似的问题 但我没有找到明确的讨论或适当的解决方案 我提到了这个que
  • 在字符串、u16string 和 u32string 之间转换

    我一直在寻找一种在 Unicode 字符串类型之间进行转换的方法 并遇到了这个方法 我不仅不完全理解该方法 没有评论 而且该文章暗示将来会有更好的方法 如果这是最好的方法 您能否指出它的工作原理 如果不是 我想听到更好方法的建议 mbsto
  • 如何在 .getJSON jQuery 中设置编码

    在我的网络应用程序中 我使用 jQuery 提交一些表单字段 getJSON 方法 我在编码方面遇到一些问题 我的应用程序的字符集是charset ISO 8859 1 但我认为这些字段是用UTF 8 我如何设置使用的编码 getJSON
  • IntentService 的 Android ServiceTestCase

    我目前正在为 Android 应用程序编写单元测试 并偶然发现了以下问题 我用ServiceTestCase测试一个IntentService像这样 Override public void setUp throws Exception s
  • 如何防止 ODataConventionModelBuilder 自动公开所有派生类型的元数据?

    我正在使用 ODataConventionModelBuilder 为 Web API OData 服务构建 Edm 模型 如下所示 ODataModelBuilder builder new ODataConventionModelBui
  • 阻止 .net 控制台应用程序关闭

    有什么方法可以阻止 NET 控制台应用程序关闭吗 我有一个遵循以下模式的应用程序 while true string x Console ReadLine StartLongRunningTaskOnSeparateThread x 问题是