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

C++如何在用户关闭控制台时执行操作并保存进度?

Windows控制台程序捕获关闭事件并保存进度的实现方法

因为无需跨平台,直接用Windows系统提供的API就能解决这个问题——通过SetConsoleCtrlHandler注册一个回调函数,捕获控制台的关闭事件(比如用户点击窗口关闭按钮、按下Ctrl+C等),在事件触发时执行进度保存逻辑,比循环检测的方式更高效可靠。

完整示例代码

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

// 模拟进度保存逻辑,替换为你的实际保存代码
void SaveProgress()
{
    std::cout << "\n正在保存程序进度...\n";
    // 示例:写入文件、更新状态等操作
    std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟保存耗时
    std::cout << "进度保存完成!\n";
}

// 控制台事件回调函数,系统会在触发对应事件时调用它
BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType)
{
    switch(dwCtrlType)
    {
        // 捕获用户关闭窗口、Ctrl+C、Ctrl+Break等终止事件
        case CTRL_CLOSE_EVENT:
        case CTRL_C_EVENT:
        case CTRL_BREAK_EVENT:
            SaveProgress();
            return TRUE; // 告知系统已处理该事件
        default:
            return FALSE;
    }
}

void func()
{
    // 模拟程序核心运行逻辑
    while(true)
    {
        std::cout << "程序正在运行...\n";
        std::this_thread::sleep_for(std::chrono::seconds(2));
    }
}

int main()
{
    // 注册控制台事件回调
    if(!SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE))
    {
        std::cerr << "注册事件回调失败,错误码:" << GetLastError() << "\n";
        return 1;
    }

    std::thread t(func);
    t.join(); // 等待子线程结束,避免主线程提前退出导致进程直接终止

    return 0;
}

关键说明

  • SetConsoleCtrlHandler是Windows专属API,需要包含<windows.h>头文件,用于向系统注册事件处理回调。
  • 回调函数中处理了多种常见的终止事件,确保不同关闭场景下都能触发进度保存。
  • 主线程必须调用t.join()等待子线程,否则主线程提前退出会直接终止整个进程,回调函数可能来不及执行。
  • 保存进度的逻辑要尽量简洁高效,系统留给事件处理的时间有限(默认几秒),超时会被强制终止进程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 05:58:14