禁用control+c关闭程序
本文关键字:关闭程序 control+c 禁用 | 更新日期: 2023-09-27 18:22:06
我有一个循环ping请求的方法,我希望当我单击Ctrl+c时,它会打断循环,并像正常cmd一样给我静态信息,但当我单击Ctrl+c时,我会得到
按任意键继续<lt;
然后程序关闭。
例如:ping google.com-t<lt;这将用无休止的循环ping谷歌,但我只需要在单击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)
,而是想使用以下内容:
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.");
}
}
我可能会晚一点,但这里有一个更好的方法,适用于所有平台:
Console.TreatControlCAsInput = true;
这里有一个相当完整的教程(带代码)。我做了一个快速测试,他们的例子确实有效(想象一下)。
这是他们的代码:
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);
}
}
}
}
另一种方法是处理Console.CancelKeyPress事件:
Console.CancelKeyPress += Console_CancelKeyPress
这允许您保留快捷方式,但根据具体情况决定是否退出。
private static void HandleConsole_CancelKeyPress(ConsoleCancelEventArgs consoleCancelEventArgs)
{
if (doNotExitYet) {
consoleCancelEventArgs.Cancel = true;
}
}