省流:现在有一条可以直接安装的路径:QQPortable。安装器会把 QQ、LiteLoaderQQNT 和 NapCat 的启动注入组件装进同一个目录,根目录只留一个
QQPortable.exe作为启动入口;启动器负责生成配置、检查重复启动,并在 QQ 完全退出后清理对应的NapCatWinBootMain.exe。
我现在的组合是 QQ 9.9.36-53644、LiteLoaderQQNT 1.4.1 和 NapCat 的 NapCatWinBootMain.exe / NapCatWinBootHook.dll。这篇文章记录的是这一套现在实际能跑通的形态,不再是一堆需要手工拼起来的脚本。
现在长什么样
安装器是单个 EXE,打开后选择空目录、QQ 版本和 LiteLoader 版本,然后等待下载和解压:

安装完成后会进入结果页,显示 QQ、LiteLoader 和安装目录:

安装出来的目录很干净:
D:\QQPortable\
QQPortable.exe 启动入口
QQ\ 官方 QQ 程序
LiteLoader\ LiteLoader 本体、插件和数据
Launcher\ NapCat 启动器、Hook 和运行时配置没有额外的 start.vbs、PowerShell 启动脚本,也没有需要用户手动维护的快捷方式。安装器不会默认创建桌面快捷方式;需要的话,把快捷方式指向根目录的 QQPortable.exe 就行。
安装
去 Releases 下载最新版 QQPortable.Installer.exe,目标目录选一个空目录,例如 D:\QQPortable。
安装器只安装程序文件,不附带插件,也不修改 QQ 的聊天数据。安装完成后 LiteLoader\plugins 是空的,插件需要自己放进去。
启动链
QQPortable.exe 启动后做这些事:
QQPortable.exe
-> 检查本次便携目录的 QQ.exe 是否已经在运行
-> 生成 Launcher\runtime\qqnt.json 和 loadLiteLoader.js
-> 设置 NAPCAT_PATCH_PACKAGE / NAPCAT_LOAD_PATH
-> 以挂起方式启动 Launcher\NapCatWinBootMain.exe
-> Hook 在内存中重定向 QQ 入口
-> loadLiteLoader.js 加载 LiteLoader
-> LiteLoader 加载插件,再进入 QQ 原本的入口Launcher\NapCatWinBootMain.exe 是 NapCat 提供的启动器,负责启动 QQ 并加载 Hook,不是 QQ 主程序本身。这里只使用它的启动注入能力,不把 NapCat Shell 的独立 QQ 部署方式混进来。
QQ 的入口重定向发生在进程内存里,不修改 QQ.exe 或 application.asar。所以 QQ 更新后一般只需要让启动器重新找到 versions 下的最新目录。
关闭窗口不等于退出
这一套最容易出问题的不是启动,而是退出。
关闭 QQ 主窗口默认只是隐藏到托盘,QQ 和 NapCatWinBootMain.exe 都还在运行。这时不能清理任何东西,否则下次从托盘恢复 QQ 时,注入链已经断了。
真正从托盘菜单退出 QQ 后,启动器会等待本次会话里的 QQ 客户端进程全部结束,再结束对应的 NapCatWinBootMain.exe、控制台宿主和启动器自身。
实现上使用的是 Windows Job:
NapCatWinBootMain.exe以挂起状态创建。- 先把它加入当前启动器的 Job,再恢复运行,避免漏掉它在早期创建的子进程。
- 单独等待 QQ 进程句柄的终止信号,而不是只看 Job 的退出通知。
- 所有客户端退出后,只结束这个 Job 里的进程,不按进程名杀其他目录的 QQ。
这样既不会在隐藏到托盘时误清理,也不会留下一个后台的 NapCatWinBootMain.exe 占用文件或端口。
4K 下的 WinForms
安装器是 .NET Framework 4.8 的 WinForms 程序。旧版在高 DPI 环境下会被 Windows 当成位图整体拉伸,文字发虚,按钮文字还可能被压扁。
现在做了三件事:
- 清单声明 per-monitor V2 DPI 感知。
- 窗口创建后通过
GetDpiForWindow读取实际 DPI,手动缩放控件尺寸。 - 字体保持点数大小,由系统按 DPI 渲染,不跟着控件尺寸一起放大。
安装器不依赖外部 .exe.config 提供 DPI 配置,发布时只需要一个 EXE。默认窗口也从原来的 780×560 放大到 1040×760,在 4K 屏幕上不会只占一小块。
版本列表为什么不只看 GitHub API
安装器需要列出 QQ 和 LiteLoader 的可用版本。最初只请求 api.github.com,未登录时每小时只有少量额度,额度用完就直接报 403,整个安装流程卡在版本列表。
现在优先使用 API,遇到 403、429、网络错误或超时会自动回退:
- 从 GitHub 的
releases.atom读取发布版本。 - QQ 版本从发布说明里提取 x64 文件名,拼接 GitHub 发布页直链。
- LiteLoader 使用发布页的
LiteLoaderQQNT.zip直链。 - 设置
GITHUB_TOKEN或GH_TOKEN可以继续使用完整 API 列表。
回退路径不消耗 API 额度,但只包含 Atom 里的最新版本;正常 API 路径能提供完整的 26 个 LiteLoader 版本。
QQ 版本目录合并了当前镜像和历史镜像,正常情况下列表是 9.9.36、9.9.35、9.9.33、9.9.32、9.9.31、9.9.30。
QQ 安装包
GitHub 上的 QQ 安装包是 7z SFX。外层归档里只有许可文件,真正的 QQ 程序在后面的内层 7z 里。
安装器的处理顺序是:
- 用内嵌的
7za.exe直接解压。 - 如果找不到
QQ.exe,扫描文件里的 7z 签名,把内层归档切出来再解压。 - 找到包含
QQ.exe的目录,复制到目标目录的QQ下。
内嵌的 7-Zip 只用于安装过程,不会留在安装后的目录里。
LiteLoader 的三个兼容补丁
QQ 9.9.36 + LiteLoaderQQNT 1.4.1 直接运行会碰到几个问题,安装器会应用三处补丁:
src/main/store.js:使用dirent.parentPath ?? dirent.path,兼容 Node 24 的目录项。src/preload.js:登录页跳过插件 preload,避免登录页被插件前端卡住。src/preload/module.js:支持.cjs预加载,并让.cjs和.js走同一段执行逻辑。
补丁匹配失败时安装器会直接报错,不会静默跳过。这样换到不兼容的 LiteLoader 版本时,问题会在安装阶段暴露,而不是启动后出现一个难以定位的空白窗口。
它没有解决的问题
这套东西仍然有明确边界:
- 只覆盖程序目录。QQ 的登录状态、聊天记录、缓存和用户数据还在
%APPDATA%\QQ和%LOCALAPPDATA%\QQ,删除便携目录不会删除聊天记录。 - LiteLoader 主仓库已经归档,针对 1.4.1 的补丁是当前验证过的路径。QQ 或 LiteLoader 后续改动结构时,安装器和补丁需要跟着更新。
- 安装包没有代码签名,Windows 可能显示安全提示。
- 安装器不捆绑插件。
LiteLoader\plugins默认是空的,插件行为和更新由用户自己负责。
如果只是想快速装一套能启动的 QQ + LiteLoader,直接下载最新版安装器即可;如果要追最新 QQ 版本或改启动方式,项目源码和 OpenSpec 文档都在 4o4E/QQPortable。
