Skip to content

设置里的「更新」能用了:下载核对、关实例,交给命令行换上后重新打开管理器 - #115

Merged
qiyinxi merged 11 commits into
ModAVD:mainfrom
qiyinxi:feat/manager-update-button
Nov 9, 2026
Merged

qiyinxi merged 11 commits into
ModAVD:mainfrom
qiyinxi:feat/manager-update-button

Conversation

@qiyinxi

@qiyinxi qiyinxi commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

管理器「设置」里的「更新」按钮现在能用了。点了以后,管理器下载、核对新版,正常关掉在运行的实例,交给命令行换上新版,换好后自动重新打开管理器。

叠在 #111 上:#111 改了同一个 update.js 的文字。先合 #111,这个 PR 的 diff 才只剩下面这些。

为什么要交给命令行

管理器不能在自己运行时换掉自己(update install 发现 ModAVD.exe 在跑就什么都不动),所以分三步:

  1. 管理器里开一个更新任务(kind 是 update,根任务,和别的任务互斥)。先下载、按清单核对、暂存好(同 modavd update prepare,实例照常开着);已经是最新就到此为止。
  2. 先预检,下面三种情况一台实例都不关、任务失败:
    • 别的进程在跑这个根目录的 ModAVD.exe 或 tools\modavd.exe(比如 modavd mcp);
    • 有实例正在新建;
    • 暂存的版本不比装着的新(这时算已经是最新)。
      预检过了,再正常关掉所有在运行的实例(同 stop --all,不取消正在新建的)。
  3. 用 host.StartOrphan 启动根目录的 tools\modavd.exe update install --after-pid <管理器 pid> --reopen <管理器程序> --reopen-arg ...,输出追加到 logs\modavd-update.log。半秒后确认它还在跑,任务才算成功,之后不再接任何新任务。约 1.5 秒后管理器退出,页面窗口自己关掉。

命令行这边:

  • 等管理器退出(最多 60 秒),换上新版,把结果写进 .update\manager-result.json。
  • 按原来的参数(--root,以及 --port、--no-window、--dev)重新打开管理器。换不上(比如有程序占着)也照样重新打开,暂存的新版留着,下次不用重下。
  • 新管理器启动时读走这份结果(超过 30 分钟的不认),页面提示一次:「已更新到 X」或「新版没有换上」加原因和建议。

开任务前就拒绝的情况:

  • 不是 Windows;
  • 管理器不知道自己的路径;
  • 根目录没有 tools\modavd.exe;
  • tools\modavd.exe 的版本和管理器不一样(旧命令行不认新选项)。

改了什么

  • internal/ui/update_apply.go(新):更新任务、关实例、交接、退出。ui.Options.Reopen 由 cmd/modavd-gui 给。
  • internal/ui/jobs.go:更新任务和别的任务互斥。backend 加了 StopTargets。
  • internal/update/handoff.go(新):命令行写给管理器的结果文件。
  • internal/cli:update install 加 --after-pid、--reopen、--reopen-arg,只能和 install 一起用,--reopen 要完整路径。
  • 页面:
    • 「更新」在检查到新版(或已经下载好)后才能点;
    • 先弹确认框,写明会关掉几台实例;
    • 进度显示在设置对话框里;
    • 交接后窗口自己关掉,重新打开后提示结果。
    • 新版要求的 AUTO-MAS 版本显示在设置和确认框里(管理器装的时候和人用命令行装一样,不带 AUTO-MAS 版本检查)。
    • 说明文字改成新的做法。
  • API.md、README:POST /api/update/apply、UpdateView 的 can_install、handoff,以及命令行新选项。

测试

  • 单测:
    • 命令行:等待、安装、重开的顺序;管理器不退出时不装但照样重开;装失败也重开;选项校验。
    • 管理器:
      • 完整交接,交接后不再接任务;
      • 已是最新、暂存版本不比装着的新时,什么都不做;
      • 下载、预检(别的程序在用、有实例正在新建、扫不了进程)、关机、启动命令行、命令行马上退出,各自失败时就停在那一步,不退出;
      • 开任务前的拒绝;互斥。
    • 结果文件:读走即删、过期不认、坏文件不认。
  • go vet 在 Windows、darwin/arm64、linux/amd64 上都通过,go test ./... 通过,update.js、actions.js 过了 node --check。
  • 变异检查:20 个变异全部被测试抓到。改坏的检查包括:
    • 不等管理器退出就装、只在成功时重开、接受相对路径;
    • 更新时放别的任务进来、交接后放任务进来;
    • 别的程序在用、有实例正在新建、暂存版本不更新时照样关实例;
    • 关不掉实例照样交接、取消正在新建的;
    • 版本不同照样交接、已是最新还关实例;
    • 启动命令行失败还退出、命令行已退出还交接、没有回路还装;
    • 把模拟器进程当成占用的程序;
    • 过期结果照样显示、结果不删。
  • 实测(测试根,0.38.2 → GitHub 上的 0.39.0,一台实例开着):
    • 检查更新找到 0.39.0;点「更新」后确认框写着会关掉 1 台实例;
    • 设置里显示下载进度(279.5 MB);
    • 实例正常关机 7.6 秒;管理器退出,页面窗口自己关掉;
    • 命令行等模拟器自己的关机辅助进程退出后换上 0.39.0,清单 303 个文件全对;
    • 结果文件内容正确,管理器按原参数重新打开。
    • 没覆盖到:
      • 重新打开的是 0.39.0 包里的管理器(还没有这个功能),所以「新管理器读走结果、页面提示」这一步只有单测。
      • 审查后加的预检、交接后不接任务、确认命令行还在,只有单测,没再上机测。预检扫进程用的是 update install 换包前那同一套扫描,实测时换包那一步走过它。

另审

另一个代理按整包更新的标准审了,结论是「能合」,没有 P0、P1。

  • 已在这个 PR 里改:
    • 交接后 1.5 秒内还能开任务(P2);
    • 先关掉全部实例才发现换不上,最可能的情况是开着 modavd mcp(P2);
    • 不提示 required_automas(P2);
    • 暂存版本不比装着的新也去关实例(P3);
    • 命令行一启动就退出时没人重开管理器(P3);
    • macOS 上按钮可点(P3)。
  • 挂在 Refs 管理器「设置」里的「更新」:交接空档、结果文件归属等审查留下的 P2/P3 ModAVD#170:
    • 管理器消失到重新打开之间,用户再双击 ModAVD.exe 的空档(P2);
    • 断网时用暂存继续(P3);
    • 结果文件的归属(P3);
    • 下载期间实例操作也被独占(P3);
    • 一个本来就有的目录符号链接问题。

和 AUTO-MAS 的关系

AUTO-MAS 用它自己的更新器、自己的更新源和 CDK,这里不改它。

  • 两个更新器之间仍然没有共用的磁盘锁,和直接用 modavd update 时一样。
  • AUTO-MAS 5.8.0 起,看到 modavd 或管理器的进程占着根目录就不换包。这里下载时管理器开着,交接后命令行在跑,所以两边同时换包的窗口和以前一样小,没有变大。

原文说 AUTO-MAS 调用 modavd update、按这里的更新源和 CDK 下载,两处都不对:
AUTO-MAS 到 v5.8.0 还是用自己的更新器,更新源和 CDK 读它自己的设置。
改成写清这里只能检查新版本、用和不用 AUTO-MAS 各自怎么更新、这里的设置
管什么。按钮照旧不可用。
- 补全组件完成:先说可以新建实例了,再说用 AUTO-MAS 的可以去添加。
- 问题包没找到 AUTO-MAS:只请用 AUTO-MAS 的附上它的日志,不用的不用管
  (管理器、命令行、summary.txt 三处);隐私说明里 AUTO-MAS 日志写成
  找到它时才有;qemu 命令行读不到时不再说多半是 AUTO-MAS 以管理员运行。
- 复制配置信息:「AUTO-MAS 版本」「用的脚本」两行并成「怎么用的
  (自己玩 / AUTO-MAS 及版本 / MAA、M9A 等脚本)」;没开实例时不再叫人
  在 AUTO-MAS 里开着实例再双击运行。
- portBase 的建议写「默认值」,不写「和 AUTO-MAS 一样」;换包恢复失败的
  提示先说下次更新时恢复。

对照旧脚本输出的测试照原来的做法,把这些有意改动的行列进对照表,基准文件不动。
所有语言都只用 ModAVD 这个名字:日志、报错、命令行帮助、问题包和配置信息的
标题都换掉,问题包文件名改成 ModAVD-问题信息-<时间>.zip。和中文相邻时加空格。

AUTO-MAS 只看错误码,不看消息文字,改名不影响对接。对照旧脚本输出的测试把
旧名字列进有意改动的对照表;对照 AUTO-MAS 原逻辑的 Python 参考和 jsonord 的
样例跟着换了文字,pycases.json 用 gen_pycases.py 重新生成。
管理器不能在自己运行时换掉自己,所以分三步:
- 更新任务(kind update,根任务,独占)先下载、核对、暂存新版,实例照常开着;
  已经是最新就到此为止。
- 正常关掉所有在运行的实例(不取消正在新建的,关不掉就失败)。
- 用 StartOrphan 启动根目录的 tools\modavd.exe update install --after-pid
  <管理器 pid> --reopen <管理器程序> --reopen-arg ...,管理器随后退出。

命令行等管理器退出、换上新版,把结果写进 .update\manager-result.json,再按
原来的参数重新打开管理器;换不上也照样打开,暂存的新版留着。新管理器启动时
读走这份结果,页面提示一次。tools\modavd.exe 不存在或版本和管理器不同时,
开任务前就拒绝。
@qiyinxi qiyinxi added enhancement New feature or request platform:windows 与 Windows 平台相关 labels Nov 9, 2026
- 关实例前先查:别的进程在跑这个根目录的 modavd(如 modavd mcp)、有实例正在
  新建、暂存的版本不比装着的新,就一台都不关(审查 P2-2、P3-1)。
- 交给命令行后不再开新任务;退出前还有任务就取消并等它收尾(P2-1)。
- 启动命令行半秒后确认它还在,不在就不退出、报错(P3-3)。
- 新版要求的 AUTO-MAS 版本显示在设置和确认框里(P2-3)。
- 只在 Windows 上允许点「更新」(P3-5)。
@qiyinxi
qiyinxi added this pull request to the merge queue Nov 9, 2026
Merged via the queue into ModAVD:main with commit 3c3ec45 Nov 9, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request platform:windows 与 Windows 平台相关

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant