You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何防止控制台关闭时程序完全终止并执行清理操作

控制台窗口关闭后执行清理操作的解决方案

Windows平台

Windows控制台程序可通过注册控制台事件处理函数捕获窗口关闭事件(CTRL_CLOSE_EVENT),触发时执行清理逻辑。

C++ 示例

#include <windows.h>
#include <iostream>

BOOL WINAPI ConsoleHandler(DWORD signal) {
    if (signal == CTRL_CLOSE_EVENT) {
        // 编写你的清理操作
        std::cout << "执行清理操作..." << std::endl;
        // 注意:清理逻辑需简短,系统仅提供几秒执行时间,超时会强制终止进程
    }
    return TRUE;
}

int main() {
    if (!SetConsoleCtrlHandler(ConsoleHandler, TRUE)) {
        std::cerr << "注册事件处理失败,错误码:" << GetLastError() << std::endl;
        return 1;
    }

    std::cout << "程序运行中,关闭窗口测试清理..." << std::endl;
    while (true) {
        Sleep(1000); // 模拟程序持续运行
    }

    return 0;
}

C# 示例

using System;
using System.Runtime.InteropServices;

class Program
{
    [DllImport("Kernel32")]
    private static extern bool SetConsoleCtrlHandler(HandlerRoutine handler, bool add);

    private delegate bool HandlerRoutine(CtrlTypes ctrlType);

    private enum CtrlTypesTypes
    {
        CTRL_C_EVENT = 0,
        CTRL_BREAK_EVENT = 1,
        CTRL_CLOSE_EVENT = 2,
        CTRL_LOGOFF_EVENT = 5,
        CTRL_SHUTDOWN_EVENT = 6
    }

    private static bool ConsoleHandler(CtrlTypes ctrlType)
    {
        if (ctrlType == CtrlTypes.CTRL_CLOSE_EVENT)
        {
            // 执行清理逻辑
            Console.WriteLine("执行清理操作...");
        }
        return true;
    }

    static void Main(string[] args)
    {
        SetConsoleCtrlHandler(new HandlerRoutine(ConsoleHandler), true);

        Console.WriteLine("程序运行中,关闭窗口测试清理...");
        while (true)
        {
            System.Threading.Thread.Sleep(1000);
        }
    }
}

Linux/Unix平台

Linux或类Unix系统中,关闭终端窗口时后台进程会收到SIGHUP信号;通过kill命令终止进程则收到SIGTERM信号,注册这两个信号的处理函数即可执行清理。

C++ 示例

#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>

void cleanup(int signal) {
    // 执行清理操作,建议使用异步安全函数(如write)
    write(STDERR_FILENO, "执行清理操作...\n", 17);
    // 清理完成后退出进程
    exit(0);
}

int main() {
    // 注册SIGHUP(终端关闭)和SIGTERM(kill命令)信号处理
    signal(SIGHUP, cleanup);
    signal(SIGTERM, cleanup);

    std::cout << "程序运行中,关闭终端测试清理..." << std::endl;
    while (true) {
        sleep(1);
    }

    return 0;
}

注意事项

  • 清理逻辑必须简洁高效,避免阻塞或执行长时间任务,系统会在触发终止事件后有限等待,超时将强制终止进程。
  • 信号处理函数中应使用异步安全的函数(如Linux下的write),避免调用可能引发死锁的函数(如printf、cout)。
  • 跨平台.NET程序仅依赖Console.CancelKeyPress无法捕获窗口关闭事件,仍需结合平台特定API实现。

内容的提问来源于stack exchange,提问作者Misiu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 02:25:47