检测控制台退出事件
本文关键字:出事件 退出 控制台 检测 | 更新日期: 2023-09-27 18:25:26
我创建了一个控制台应用程序,它有一个将kinect流存储到硬盘的方法。我想捕获控制台退出事件以关闭kinect流,因为当控制台退出关闭事件时我会遇到问题。我想找到一种方法来检测控制台的退出事件。我遇到了如下的解决方案。我将以下代码添加到我的应用程序中:
[DllImport("Kernel32")]
private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);
private delegate bool EventHandler(CtrlType sig);
static EventHandler _handler;
enum CtrlType
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT = 1,
CTRL_CLOSE_EVENT = 2,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT = 6
}
private static bool Handler(CtrlType sig)
{
switch (sig)
{
case CtrlType.CTRL_C_EVENT:
case CtrlType.CTRL_LOGOFF_EVENT:
case CtrlType.CTRL_SHUTDOWN_EVENT:
case CtrlType.CTRL_CLOSE_EVENT:
default:
return false;
}
}
并且在主要功能:
Program obj = new Program(dirPath + args[3] + "_" + args[4]);
_handler += new EventHandler(Handler);
SetConsoleCtrlHandler(_handler, true);
Console.ReadLine();
我首先在思考是否可以将处理程序事件导入到布尔变量,其次如何将其作为程序构造函数的输入来关闭流。
编辑:我的程序构造函数:
public Program(string filePath)
{
Thread thread = new Thread(() => writeRGSStream(file));
thread.Start();
writeSkelFiles(file);
}
我想在writeRGSStream方法中输入标志。我可以打吗
SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true);
在该方法内部以获取标志值?
看看这个例子,它工作得很好:
主
private static bool isclosing = false;
static void Main(string[] args)
{
SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true);
Console.WriteLine("CTRL+C,CTRL+BREAK or suppress the application to exit");
while (!isclosing) ;
}
控制台检查
private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
{
// Put your own handler here
switch (ctrlType)
{
case CtrlTypes.CTRL_C_EVENT:
isclosing = true;
Console.WriteLine("CTRL+C received!");
break;
case CtrlTypes.CTRL_BREAK_EVENT:
isclosing = true;
Console.WriteLine("CTRL+BREAK received!");
break;
case CtrlTypes.CTRL_CLOSE_EVENT:
isclosing = true;
Console.WriteLine("Program being closed!");
break;
case CtrlTypes.CTRL_LOGOFF_EVENT:
case CtrlTypes.CTRL_SHUTDOWN_EVENT:
isclosing = true;
Console.WriteLine("User is logging off!");
break;
}
return true;
}
和WinAPI部分:
#region unmanaged
// Declare the SetConsoleCtrlHandler function
// as external and receiving a delegate.
[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
}
#endregion
使用CancelKeyPress事件(在CTRL+C上激发)。
Console.CancelKeyPress += Console_CancelKeyPress;
在关闭之前做一些事情
private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
Process.GetCurrentProcess().CloseMainWindow();
}
希望这就是你想要做的。
return false;
这并没有达到你所希望的效果。您不能取消关闭请求,返回值只是告诉Windows它是否应该调用任何其他注册的处理程序。因此,无论您返回true还是false都不会影响结果,操作系统总是会终止程序。
因此,您需要做的任何事情都必须在回调方法中完成。小心你的选择非常有限。毕竟,你的主线程正忙于写入该文件,你无法删除它。这也不是一个真正的解决方案,如果你的应用程序因任何其他原因终止,你仍然会遇到麻烦。就像未处理的异常一样,用户用任务管理器杀死它,或者有人被电源线绊倒并拔下机器。
只需编写更智能的代码,使用临时名称创建文件,并在完成编写后重命名文件。现在,您永远不在乎程序因任何原因而中断。