我创建了一个控制台应用程序,它有一个将kinect流存储到硬盘的方法。我想捕获控制台退出事件以关闭kinect流,因为我在控制台退出close事件时遇到问题。我想找到一种方法来检测控制台的退出事件。我遇到了类似以下one的解决方案。我将以下代码添加到我的应用程序中:
[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);
在该方法内部以获取标志值?
答案 0 :(得分:3)
看看这个例子,它运行正常:
主要
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
答案 1 :(得分:1)
return false;
这不符合你的期望。您无法取消关闭请求,返回值仅告诉Windows是否应该调用任何其他注册的处理程序。因此,无论您返回true还是false都不会影响结果,操作系统将始终终止该程序。
因此,您需要做的任何事情都必须在回调方法中完成。请注意,您的选择非常有限。毕竟,你的主线程正在忙着写那个文件,你无法删除它。它也不是一个真正的解决方案,如果您的应用因任何其他原因而终止,您仍然会遇到麻烦。就像一个未处理的异常,用户使用任务管理器将其查杀,或者某人绊倒电源线并拔掉机器。
只需编写更智能的代码,使用临时名称创建文件,并在完成编写后重命名该文件。现在你永远不关心你的程序因任何原因而被打断。
答案 2 :(得分:1)
使用CancelKeyPress事件(在CTRL + C上触发)。
Console.CancelKeyPress += Console_CancelKeyPress;
在此之前做事情
private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
Process.GetCurrentProcess().CloseMainWindow();
}
希望这是你想要做的。