我知道,我必须使用setconsolehandler()如果我要管理控制台关闭事件。

我不知道如何阻止CTRL_CLOSE_EVENT。我试图返回false / true,如果能抓住这一事件,但没有成功。

下面是我到目前为止(谢谢你,安东Gogolev!)

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

public delegate bool HandlerRoutine(CtrlTypes CtrlType);

public enum CtrlTypes{
    CTRL_C_EVENT = 0,
    CTRL_BREAK_EVENT,
    CTRL_CLOSE_EVENT,
    CTRL_LOGOFF_EVENT = 5,
    CTRL_SHUTDOWN_EVENT
}

private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
{ 
    if(ctrlType == CtrlTypes.CTRL_CLOSE_EVENT)
        return false;// I have tried true and false and viceversa with the return   
                     // true/false but I cant seem to get it right.
    return true;
}


//and then I use this to call it
SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true);

也就是它可以运行一个新的线程来监视控制台是否关闭和块关闭,如果主线程在做某件事的中间?

有帮助吗?

解决方案

SetConsoleCtrlHandler() 文档说:

  

在系统中,当用户关闭控制台,注销,或关闭该系统,以便该过程有机会终止之前清理产生CTRL_CLOSE_EVENT,CTRL_LOGOFF_EVENT,和CTRL_SHUTDOWN_EVENT信号。

这意味着处理CTRL + C或CTRL + BREAK事件时不同,你的进程没有得到机会,取消关闭,注销或关机。

其他提示

其实你可以阻止它(我至少转载此在Windows XP)。例如,如果在你的处理器,你有无限循环和睡眠,这会从永远终止阻止这一进程(或者至少很长一段时间,或直到用户通过任务管理器终止进程)。

如果你真的需要启动一个线程,你可以使用(在C#AutoResetEvent)等待状态,并开始你的线程(尽管一个新的线程可能不需要在大多数情况下),然后通知等待状态时,你的线程完了。然而,仅仅在处理程序做任何清理就足以在大多数情况下。

如果在最坏的情况下,你也永远等待下去,该过程将保持运行,你就可以看到它时,你(至少在Windows XP)重新登录。然而,这会导致桌面才去注销屏幕(在等待您的应用程序了退出)暂停大约20秒钟,然后在注销屏幕(我猜当它试图得到第二次)再次暂停。当然,我强烈建议不要永远等待;对于任何长期运行的东西,你真的应该把这个服务。

我发现了一个可能的“黑客”,可以防止从封闭的应用,同时仍然服从整齐控制台关闭请求。 尤其是,这是合适的,我认为,对于已经创造了一个控制台的“额外”的GUI应用程序。 从MSDN文档,在其中处理程序Ctrl键被称为新线程的点在该过程中创建的调用处理程序。我的解决办法,那么,是杀死入侵的袭警线程之前的默认处理程序可以调用了ExitProcess。在处理程序例程(代码在C ++):

// Detach Console:
FreeConsole();
// Prevent closing:
ExitThread(0);
return TRUE; // Not reached

编辑:看来这确实会引起一些问题,如可以预期的,我想。到AllocConsole的后续调用()无限期挂起,所以我怀疑离开螺纹过早未能正确地进行清理。

修改2:

要上述澄清,我已发现没有直接问题同继续运行该程序。但请记住,我们已经强制终止该KERNEL32创造了一个线程,所以里面KERNEL32任何资源可能处于不确定状态。这可能导致不可预见的问题当程序继续运行。

大多数情况下,我认为,这些问题将关系到控制台API。就像提到,AllocConsole无法从该点开始工作(它将应用程序挂起),所以程序无法打开一个新的控制台。这极有可能是其他控制台功能也将失败。基本上,任何你从该点起做以任何方式(直接或间接)调用到KERNEL32受不确定的行为,但我怀疑,在实践中也不会有的控制台功能之外的任何问题。

我的结论是,你应该避免这种方法,如果可能的话,但是如果过早终止更糟糕的是,那么这可以被认为是紧急情况下的变通,要谨慎,谨慎使用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top