当打开的控制台窗口关闭时,如何防止我的程序关闭

How can I prevent my program from closing when a open console window is closed?

本文关键字:何防止 我的 程序 控制台 窗口      更新时间:2023-10-16

我正试图从主程序(Win32)打开控制台。我找到了一些代码,它很有效,但我不明白。我遇到的问题是,当我在控制台上单击X时,它也会关闭程序。

大概我有这个:

int APIENTRY WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) {
  // create the main program window, classes registered, etc...
  hwnd = CreateWindowEx(0, csClassName, "theNewTimer", WS_POPUP | WS_CLIPCHILDREN, 300, 0, WINDOW_WIDTH, WINDOW_HEIGHT, HWND_DESKTOP, NULL, hThisInstance, NULL);
  ShowWindow (hwnd, nFunsterStil);
  // and now the console
  AllocConsole();
  HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
  int hCrt = _open_osfhandle((long) handle_out, _O_TEXT);
  FILE* hf_out = _fdopen(hCrt, "w");
  setvbuf(hf_out, NULL, _IONBF, 1);
  *stdout = *hf_out;
  HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
  hCrt = _open_osfhandle((long) handle_in, _O_TEXT);
  FILE* hf_in = _fdopen(hCrt, "r");
  setvbuf(hf_in, NULL, _IONBF, 128);
  *stdin = *hf_in;

// and then the message loop concluding

我在谷歌上搜索了一些,但不知道自己在读什么。

您可以做的一件事是禁用控制台窗口上的关闭按钮:

HWND hwnd = ::GetConsoleWindow();
if (hwnd != NULL)
{
   HMENU hMenu = ::GetSystemMenu(hwnd, FALSE);
   if (hMenu != NULL) DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
}

我认为这是不可能的。在一个HandlerRoutine的MSDN文档中,有这样一句话。

CTRL_CLOSE_EVENT、CTRL_LOGOFF_EVENT和CTRL_SHUTDOWN_EVENT信号使进程有机会在终止前进行清理。

我读到这里是说CTRL_CLOSE_EVENT是建议性的,不管怎样,该过程都将退出。我的猜测是,当系统发送CTRL_CLOSE_EVENT时,它会启动一个计时器。进程可以继续运行一段时间,但最终,操作系统只会单方面终止进程。

这是我注册的管理员

BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType) {
   switch (dwCtrlType) {
       case CTRL_C_EVENT:
       case CTRL_CLOSE_EVENT:
           return TRUE; // breakpoint set here
       default:
           return FALSE;
   }
}

以下是我在呼叫AllocConsole:后注册处理程序的方式

BOOL result = SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE /* Add */);
assert(result);

我在标记为//breakpoint set here的行上设置了一个断点。然后,我在Visual Studio调试器下运行了该进程。当控制台窗口聚焦时,我按下了Ctrl+C。我的断点被击中了,我可以通过我的处理程序,回到KernelBase.dll!CtrlRoutine等等。当我让进程恢复正常执行时,进程一直在运行。

然而,当我关闭控制台窗口时,我的处理程序确实被调用了,但我无法跟踪它的执行情况。我可以执行几次单步执行,但随后进程就退出了。Visual Studio报告"程序'[10644]Win32Project.exe'已退出,代码为-103741510(0xc000013a)。"

0xc000013a是STATUS_CONTROL_C_EXIT:

c:ToolsERR>Err.exe 0xc000013a
# for hex 0xc000013a / decimal -1073741510 :
  STATUS_CONTROL_C_EXIT                                         ntstatus.h
# {Application Exit by CTRL+C}
# The application terminated as a result of a CTRL+C.
# 1 matches found for "0xc000013a"