禁用control+c关闭程序

发布于 2025-01-01 17:41:46 字数 2020 浏览 1 评论 0原文

我有一个循环 ping 请求的方法,我希望当我单击 Ctrl+c 时,它会打破循环并为我提供像普通 cmd 一样的静态信息,但是当我点击 Ctrl+c,我得到

按任意键继续... <<

然后程序关闭。

例如: ping google.com -t <<这将通过无限循环 ping google,但仅当我单击 Ctrl+c 时才需要打破循环

private void _t(string website)
{
    Ping pingSender = new Ping();
    string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    byte[] buffer = Encoding.ASCII.GetBytes(data);
    int timeout = 10000;
    try
    {
        PingOptions options = new PingOptions(64, false);
        PingReply send0 = pingSender.Send(website, timeout, buffer, options);
        Console.WriteLine("\nPinging {0} [{1}] With {2} bytes of data :", website, send0.Address.ToString(), send0.Buffer.Length);
        while (1 < 2)
        {
            PingReply reply = pingSender.Send(website, timeout, buffer, options);

            if (reply.Status == IPStatus.Success)
            {
                Console.WriteLine("Reply from {0}: Bytes {1} time={2} TTL={3}", reply.Address.ToString(), reply.Buffer.Length, reply.RoundtripTime / 5, reply.Options.Ttl);
            }
            else
            {
                Console.WriteLine("Request timed out.");
            }
        }
    }
    catch
    {
        Console.WriteLine("Ping request could not find host {0} ", website + ".Please check the name and try again.");
    }
}

,而不是使用 while (1<2)< /code>,我想使用类似的东西:

while (ConsoleKeyInfo.Equals("Control + c") not clicked) // sure it is wrong , but that`s what I wanna achieve
{
    PingReply reply = pingSender.Send(website, timeout, buffer, options);

    if (reply.Status == IPStatus.Success)
    {
        Console.WriteLine("Reply from {0}: Bytes {1} time={2} TTL={3}",        reply.Address.ToString(), reply.Buffer.Length, reply.RoundtripTime / 5, reply.Options.Ttl);
    }
    else
    {
        Console.WriteLine("Request timed out.");
    }
}

I have a method that loops ping requests, and I'd like when I click Ctrl+c, it break the loop and give me statics like the normal cmd, but when I click Ctrl+c, I get

Press Any Key To Continue... <<

and then program closes .

For example : ping google.com -t << that will ping google with endless loop, but I need to break the loop ONLY when I click Ctrl+c

private void _t(string website)
{
    Ping pingSender = new Ping();
    string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    byte[] buffer = Encoding.ASCII.GetBytes(data);
    int timeout = 10000;
    try
    {
        PingOptions options = new PingOptions(64, false);
        PingReply send0 = pingSender.Send(website, timeout, buffer, options);
        Console.WriteLine("\nPinging {0} [{1}] With {2} bytes of data :", website, send0.Address.ToString(), send0.Buffer.Length);
        while (1 < 2)
        {
            PingReply reply = pingSender.Send(website, timeout, buffer, options);

            if (reply.Status == IPStatus.Success)
            {
                Console.WriteLine("Reply from {0}: Bytes {1} time={2} TTL={3}", reply.Address.ToString(), reply.Buffer.Length, reply.RoundtripTime / 5, reply.Options.Ttl);
            }
            else
            {
                Console.WriteLine("Request timed out.");
            }
        }
    }
    catch
    {
        Console.WriteLine("Ping request could not find host {0} ", website + ".Please check the name and try again.");
    }
}

But instead of using while (1<2), I want to use something like :

while (ConsoleKeyInfo.Equals("Control + c") not clicked) // sure it is wrong , but that`s what I wanna achieve
{
    PingReply reply = pingSender.Send(website, timeout, buffer, options);

    if (reply.Status == IPStatus.Success)
    {
        Console.WriteLine("Reply from {0}: Bytes {1} time={2} TTL={3}",        reply.Address.ToString(), reply.Buffer.Length, reply.RoundtripTime / 5, reply.Options.Ttl);
    }
    else
    {
        Console.WriteLine("Request timed out.");
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

葬花如无物 2025-01-08 17:41:46

我可能有点晚了,但这是一种更好的方法,适用于所有平台:

Console.TreatControlCAsInput = true;

I might be a little late, but here's a better way, one that works on all platforms:

Console.TreatControlCAsInput = true;
痴情换悲伤 2025-01-08 17:41:46

有一个相当完整的教程(带有代码)此处。我做了一个快速测试,他们的例子确实有效(想象一下)。

这是他们的代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Text;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Threading;
using System.Reflection;

namespace ConsoleApplication1
{

    class ControlChecker
    {
        #region GLOBAL VARS
        private static readonly Mutex mutex = new Mutex(true, Assembly.GetExecutingAssembly().GetName().CodeBase);
        private static bool _userRequestExit = false;
        private static bool _doIStop = false;
        static HandlerRoutine consoleHandler;
        #endregion

        [DllImport("Kernel32")]
        public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);

        // A delegate type to be used as the handler routine for SetConsoleCtrlHandler.
        public delegate bool HandlerRoutine(CtrlTypes CtrlType);

        // An enumerated type for the control messages sent to the handler routine.
        public enum CtrlTypes
        {
            CTRL_C_EVENT = 0,
            CTRL_BREAK_EVENT,
            CTRL_CLOSE_EVENT,
            CTRL_LOGOFF_EVENT = 5,
            CTRL_SHUTDOWN_EVENT
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ctrlType"></param>
        /// <returns></returns>
        private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
        {
            // Put your own handler here
            switch (ctrlType)
            {
                case CtrlTypes.CTRL_C_EVENT:
                    _userRequestExit = true;
                    Console.WriteLine("CTRL+C received, shutting down");
                    break;

                case CtrlTypes.CTRL_BREAK_EVENT:
                    _userRequestExit = true;
                    Console.WriteLine("CTRL+BREAK received, shutting down");
                    break;

                case CtrlTypes.CTRL_CLOSE_EVENT:
                    _userRequestExit = true;
                    Console.WriteLine("Program being closed, shutting down");
                    break;

                case CtrlTypes.CTRL_LOGOFF_EVENT:
                case CtrlTypes.CTRL_SHUTDOWN_EVENT:
                    _userRequestExit = true;
                    Console.WriteLine("User is logging off!, shutting down");
                    break;
            }

            return true;
        }

        /// <summary>
        /// Main entry point
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>        
        static int Main(string[] args)
        {
            try
            {
                //make sure we only have one....
                if (!mutex.WaitOne(TimeSpan.Zero, true))
                {
                    Console.WriteLine("Another instance already running");
                    Thread.Sleep(5000);
                    return 1;
                }

                //save a reference so it does not get GC'd
                consoleHandler = new HandlerRoutine(ConsoleCtrlCheck);

                //set our handler here that will trap exit
                SetConsoleCtrlHandler(consoleHandler, true);

                DoMyTask();

                return 0;
            }
            catch (Exception x)
            {
                Console.WriteLine("Main Error [{0}]", x.Message);
                return -1;
            }
        }



        /// <summary>
        /// Run the export
        /// </summary>
        /// <param name="pAuthority"></param>
        /// <returns></returns>
        private static void DoMyTask()
        {
            //execcute until we have no more records to process
            while (!_doIStop)
            {
                //did user request exit?
                if (_userRequestExit)
                {
                    _doIStop = true;    //set flag to exit loop.  Other conditions could cause this too, which is why we use a seperate variable
                    Console.WriteLine("Shutting down, user requested exit");
                    break;
                }

                //do some other stuff here
                Console.WriteLine(String.Format("{0}, no exit requested yet...", DateTime.Now));
                //sleep 1 second
                Thread.Sleep(1000);    
            }
        }
    }
}

There is a fairly complete tutorial (with code) here. I did a quick test and their example actually worked (imagine that).

Here is their code:

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Text;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Threading;
using System.Reflection;

namespace ConsoleApplication1
{

    class ControlChecker
    {
        #region GLOBAL VARS
        private static readonly Mutex mutex = new Mutex(true, Assembly.GetExecutingAssembly().GetName().CodeBase);
        private static bool _userRequestExit = false;
        private static bool _doIStop = false;
        static HandlerRoutine consoleHandler;
        #endregion

        [DllImport("Kernel32")]
        public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);

        // A delegate type to be used as the handler routine for SetConsoleCtrlHandler.
        public delegate bool HandlerRoutine(CtrlTypes CtrlType);

        // An enumerated type for the control messages sent to the handler routine.
        public enum CtrlTypes
        {
            CTRL_C_EVENT = 0,
            CTRL_BREAK_EVENT,
            CTRL_CLOSE_EVENT,
            CTRL_LOGOFF_EVENT = 5,
            CTRL_SHUTDOWN_EVENT
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ctrlType"></param>
        /// <returns></returns>
        private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
        {
            // Put your own handler here
            switch (ctrlType)
            {
                case CtrlTypes.CTRL_C_EVENT:
                    _userRequestExit = true;
                    Console.WriteLine("CTRL+C received, shutting down");
                    break;

                case CtrlTypes.CTRL_BREAK_EVENT:
                    _userRequestExit = true;
                    Console.WriteLine("CTRL+BREAK received, shutting down");
                    break;

                case CtrlTypes.CTRL_CLOSE_EVENT:
                    _userRequestExit = true;
                    Console.WriteLine("Program being closed, shutting down");
                    break;

                case CtrlTypes.CTRL_LOGOFF_EVENT:
                case CtrlTypes.CTRL_SHUTDOWN_EVENT:
                    _userRequestExit = true;
                    Console.WriteLine("User is logging off!, shutting down");
                    break;
            }

            return true;
        }

        /// <summary>
        /// Main entry point
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>        
        static int Main(string[] args)
        {
            try
            {
                //make sure we only have one....
                if (!mutex.WaitOne(TimeSpan.Zero, true))
                {
                    Console.WriteLine("Another instance already running");
                    Thread.Sleep(5000);
                    return 1;
                }

                //save a reference so it does not get GC'd
                consoleHandler = new HandlerRoutine(ConsoleCtrlCheck);

                //set our handler here that will trap exit
                SetConsoleCtrlHandler(consoleHandler, true);

                DoMyTask();

                return 0;
            }
            catch (Exception x)
            {
                Console.WriteLine("Main Error [{0}]", x.Message);
                return -1;
            }
        }



        /// <summary>
        /// Run the export
        /// </summary>
        /// <param name="pAuthority"></param>
        /// <returns></returns>
        private static void DoMyTask()
        {
            //execcute until we have no more records to process
            while (!_doIStop)
            {
                //did user request exit?
                if (_userRequestExit)
                {
                    _doIStop = true;    //set flag to exit loop.  Other conditions could cause this too, which is why we use a seperate variable
                    Console.WriteLine("Shutting down, user requested exit");
                    break;
                }

                //do some other stuff here
                Console.WriteLine(String.Format("{0}, no exit requested yet...", DateTime.Now));
                //sleep 1 second
                Thread.Sleep(1000);    
            }
        }
    }
}
燕归巢 2025-01-08 17:41:46

另一种方法是处理 Console.CancelKeyPress 事件:

Console.CancelKeyPress += Console_CancelKeyPress

这允许您保留快捷方式,但根据具体情况决定是否退出。

private static void HandleConsole_CancelKeyPress(ConsoleCancelEventArgs consoleCancelEventArgs)
{
    if (doNotExitYet) {
        consoleCancelEventArgs.Cancel = true;
    }
}

Another way is to handle the Console.CancelKeyPress event:

Console.CancelKeyPress += Console_CancelKeyPress

This allows you to keep the shortcut, but decide whether to exit on a case by case basis.

private static void HandleConsole_CancelKeyPress(ConsoleCancelEventArgs consoleCancelEventArgs)
{
    if (doNotExitYet) {
        consoleCancelEventArgs.Cancel = true;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文