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

如何正确退出注入进程的DLL内部的窗口过程?

问题排查点

  • 第一个核心错误:你在ExitProcess钩子中直接调用WndProc是完全错误的。PostQuitMessage的作用是给当前执行该函数的线程的消息队列投递WM_QUIT消息,你在钩子线程调用WndProc,相当于在钩子线程执行PostQuitMessage,根本不会投递到你跑窗口逻辑的次级线程的消息队列,次级线程的GetMessage永远拿不到退出信号,线程无法退出,自然会导致进程残留。
  • 第二个逻辑错误:你的WndProc中WM_COPYDATA的分支没有加break,执行完WM_COPYDATA的逻辑后会直接掉落到下方的WM_DESTROY/WM_QUIT分支,提前触发退出逻辑,属于未定义行为。
  • 第三个遗漏点:你没有等待次级线程完全退出就直接调用原ExitProcess,即使线程收到退出信号,也可能因为还没完成资源清理就被强制终止,引发残留问题。
  • 额外冗余问题:消息-only窗口不需要调用ShowWindow和UpdateWindow,这两行属于无效代码可以删掉。

修复方案

  1. 先修正WndProc的分支逻辑,补全break,补充标准窗口销毁流程:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_COPYDATA:
        {
          //....
          break; // 补充这行避免分支掉落
        }
        case WM_CLOSE:
            DestroyWindow(hwnd);
            break;
        case WM_DESTROY:
            OutputDebugString(L"WM_DESTROY");
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}
  1. 修改ExitProcess钩子逻辑,改为给窗口投递消息,等待次级线程退出后再执行原退出流程:
void ExitProcess_Hook(UINT uExitCode)
{
    OutputDebugString(L"ExitProcess_Hook!");

    // 消息会自动路由到创建窗口的次级线程处理
    PostMessageW(dummy_hwnd, WM_CLOSE, 0, 0);
    // 等待次级线程完全退出
    if(thread.valid())
    {
        thread.wait();
    }
    // 清理注册的窗口类资源
    UnregisterClass(dummy_class_name, 0);

    return ExitProcess(uExitCode);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 04:57:03