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

MFC系统重启时WM_ENDSESSION未触发OnCloseDocument致数据丢失问题

问题根因

手动发送携带TRUE结束标识的WM_ENDSESSION消息测试时,消息的lParam参数不携带ENDSESSION_CLOSEAPP标记,MFC框架会走默认分支调用CloseAllDocuments(),正常触发OnCloseDocument()。
而Windows更新、MSI安装完成后触发的系统重启,是通过Restart Manager(重启管理器)发起的关闭流程,此时发送的WM_ENDSESSION消息lParam会携带ENDSESSION_CLOSEAPP标记。对照MFC默认实现,命中该分支后如果检测到已初始化数据恢复处理器,会直接返回,将保存逻辑寄托在后续WM_CLOSE消息的自动保存流程中,不会主动执行文档关闭逻辑,因此OnCloseDocument()不会被调用,存在未保存数据丢失风险。

解决方案

根据是否需要保留Restart Manager相关特性,可选择以下任意一种方案:

  • 方案1:完全关闭Restart Manager支持
    如果不需要系统重启后自动重启应用、崩溃/重启后自动恢复文档的特性,直接在应用类构造函数中关闭Restart Manager支持即可:

    // 关闭所有Restart Manager相关功能
    m_dwRestartManagerSupportFlags = 0;
    

    关闭后MFC不会初始化CDataRecoveryHandler实例,默认OnEndSession逻辑中判断数据恢复处理器为空,不会进入提前return的分支,会正常执行CloseAllDocuments(TRUE)调用,触发OnCloseDocument()。

  • 方案2:重写主框架窗口的OnEndSession逻辑
    如果需要保留部分Restart Manager特性,可在主框架窗口(CFrameWnd派生类)中重写OnEndSession方法,覆盖默认的提前返回逻辑:

    void CMainFrame::OnEndSession(BOOL bEnding)
    {
        if (!bEnding)
        {
            Default();
            return;
        }
        // 所有会话结束场景均正常执行文档关闭流程
        AfxOleSetUserCtrl(TRUE);
        AfxGetApp()->CloseAllDocuments(TRUE);
        AfxGetApp()->ExitInstance();
    }
    

    该方案下无论是否是Restart Manager触发的会话结束,都会走和手动测试一致的文档关闭流程,保证OnCloseDocument()被调用。注意WM_ENDSESSION消息系统仅给5秒处理时间,若文档保存逻辑耗时较长,存在被系统强制终止的可能。

  • 方案3:在WM_CLOSE分支补全文档关闭逻辑(推荐)
    根据MFC源码注释,命中ENDSESSION_CLOSEAPP分支后,系统会后续发送WM_CLOSE消息,该消息给应用预留30秒处理时间,比WM_ENDSESSION的5秒窗口更充裕。可重写主框架窗口的OnClose方法,判断为Restart Manager触发的关闭场景时主动执行文档关闭:

    void CMainFrame::OnClose()
    {
        CDataRecoveryHandler* pHandler = AfxGetApp()->GetDataRecoveryHandler();
        if (pHandler != nullptr && pHandler->GetShutdownByRestartManager())
        {
            // Restart Manager触发关闭时,主动关闭所有文档,不依赖自动保存
            AfxGetApp()->CloseAllDocuments(TRUE);
        }
        CFrameWnd::OnClose();
    }
    

    该方案既保留了Restart Manager的重启支持能力,又利用了更长的消息处理超时窗口,同时不依赖自动保存机制,能保证所有未保存数据在OnCloseDocument()流程中被正常处理。

注意:不建议依赖Restart Manager的自动保存能力,自动保存的时间间隔内产生的修改无法被持久化,存在固有丢数据风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:22:10