停止从正在关闭的.NET控制台应用程序 [英] Stop a .net console app from being closed

查看:234
本文介绍了停止从正在关闭的.NET控制台应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法阻止从正在关闭的.NET控制台应用程序?我有一个应用程序,遵循以下模式:

 ,而(真)
{
    字符串x =到Console.ReadLine();
    StartLongRunningTaskOnSeparateThread(X);
}
 

的问题是,它可能关闭控制台窗口(并因此切断长期运行的任务)。是否有对Forms.OnClosing事件的equivilent控制台应用程序?

编辑 - 我并不想创造的东西,是不可能杀人,只是也许会给出警告e..g

EDIT2 - preventing通过的X按钮,一个不合时宜的出口比堵按Ctrl-C更重要(我用 Console.TreatControlCAsInput = TRUE; )。假设用于此目的,任何人谁触发了任务管理器要杀死节目这么多,他们应该可以。而终端用户宁愿看到一个警告不是意外取消其长期运行的任务。

解决方案

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

以下程序会检测到CTRL-C和;&安培; CTRL-BREAK,并会继续下去。

编辑:删除的X按钮

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;
使用System.ComponentModel;
使用了System.Runtime.InteropServices;
使用System.Diagnostics程序;

命名空间DoNotCloseMe
{
    类节目
    {

        常量字符串_title =请不要关闭 - 重要的计划;

        静态无效的主要(字串[] args)
        {

            Console.Title = _title;

            IntPtr的HMENU = Process.GetCurrentProcess()MainWindowHandle。
            IntPtr的hSystemMenu = GetSystemMenu(HMENU,假);

            EnableMenuItem(hSystemMenu,SC_CLOSE,MF_GRAYED);
            RemoveMenu(hSystemMenu,SC_CLOSE,MF_BYCOMMAND);

            WriteConsoleHeader();

            //这个功能似乎只被调用一次。
            //后调用主循环()以下,CTRL-C和;&安培; CTRL-BREAK原因到Console.ReadLine()返回NULL
            Console.CancelKey preSS + =(发件人,E)=>
            {
                Console.WriteLine(清理code在CancelKey preSS处理程序调用。);
                Console.WriteLine(键pressed:{0},e.SpecialKey.ToString());
                System.Threading.Thread.Sleep(1000);
                主循环();
                //该应用程序直接执行此委托后终止。
            };

            主循环();

        }

        私有静态无效主循环()
        {
            而(真)
            {
                WriteConsoleHeader();
                字符串x =到Console.ReadLine();
                如果(!String.IsNullOrEmpty(X))
                {
                    开关(x.ToUpperInvariant())
                    {
                        案退出:
                        案退出:
                            System.Environment.Exit(0);
                            打破;
                        默认:
                            StartLongRunningTaskOnSeparateThread(X);
                            打破;
                    }

                }
            }
        }

        私有静态无效StartLongRunningTaskOnSeparateThread(字符串命令)
        {
            变种BG =新System.ComponentModel.BackgroundWorker();
            bg.WorkerReportsProgress = FALSE;
            bg.WorkerSupportsCancellation = FALSE;

            bg.DoWork + =(发件人,参数)=>
            {
                VAR睡眠时间=(新的随机())下(5000)。
                System.Threading.Thread.Sleep(睡眠时间);
            };


            bg.RunWorkerCompleted + =(发件人,参数)=>
            {
                Console.WriteLine(条命令完成:{0}命令);
            };

            bg.RunWorkerAsync();

        }

        私有静态无效WriteConsoleHeader()
        {
            Console.Clear();
            Console.WriteLine(新的字符串(*,Console.WindowWidth  -  1));
            Console.WriteLine(_title);
            Console.WriteLine(新的字符串(*,Console.WindowWidth  -  1));
            Console.WriteLine(请不要关闭这个程序。);
            Console.WriteLine(这是保持空间/时间连续体。);
            Console.WriteLine(如果你关闭它,Q会不高兴,你会被同化。);
            Console.WriteLine(新的字符串(*,Console.WindowWidth  -  1));
            Console.WriteLine(发展模式:使用\EXIT \或\QUIT \退出应用程序。);
            Console.WriteLine(新的字符串(*,Console.WindowWidth  -  1));
        }

        #地区的非网管型

        [的DllImport(user32.dll中)
        静态外部布尔EnableMenuItem(IntPtr的HMENU,UINT uIDEnableItem,UINT uEnable);

        [的DllImport(user32.dll中)
        静态外部的IntPtr GetSystemMenu(IntPtr的的HWND,布尔bR​​evert);

        [的DllImport(user32.dll中)
        静态外部的IntPtr RemoveMenu(IntPtr的HMENU,UINT nPosition,UINT wFlags);

        内部常量UINT SC_CLOSE = 0xF060;
        内部常量UINT MF_GRAYED = 00000001;
        内部常量UINT MF_BYCOMMAND = 00000000;

        #endregion
    }
}
 

Is there any way to stop a .NET console app from being closed? I've got an app that follows this pattern:

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

The problem is that it's possible to close the console window (and therefore cut off the long running task). Is there an equivilent of the Forms.OnClosing event for console apps?

EDIT - I'm not trying to create something that's impossible to kill, just maybe give a warning message e..g "hey i'm not done yet. are you sure you want to close me?"

EDIT2 - Preventing an untimely exit via the 'x' button is more important than blocking Ctrl-C (I used Console.TreatControlCAsInput = true;). Assume for this purpose that anyone who fires up task manager wants to kill the program so much that they deserve to be able to. And that the end user would rather see a warning than accidentally cancel their long running task.

解决方案

Here is my attempt to solve this problem. Task Manager can still close the application though. But, my thought was to try and detect when it is being closed and then relaunch it. However, I didn't implement that part.

The following program will detect a CTRL-C && CTRL-BREAK and will keep on going.

EDIT: Removed the "X" Button

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控制台应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆