Skip to content

Repository files navigation

Go 多软件热更新管理与下载

一个程序包含两个模式:

  • server:动态创建任意数量的软件更新模块,管理各软件的当前版本、发布文件、更新说明和完整历史。
  • client:检查指定软件的版本;版本不一致时下载任意类型的文件并原子替换目标文件。

只使用 Go 标准库,支持 Windows 和 Linux。客户端只下载文件,不会自动执行。

管理后台预览

软件管理页面

1. 启动管理端

hot-updater.exe -mode server -listen 127.0.0.1:8080 -data-dir update-data -admin-user admin -admin-password "你的密码"

浏览器打开:

http://127.0.0.1:8080/admin/

默认账号为 admin,服务端不内置默认密码。首次启动必须通过 -admin-password 或 UPDATE_ADMIN_PASSWORD 提供密码。管理端提供独立登录页、12 小时登录会话和退出登录。登录后可以修改密码;修改密码会立即注销所有旧会话,新密码以加盐哈希形式保存在 -data-dir/credentials.json,重启后仍然有效。

后台采用侧边栏分页布局:

/admin/           概览
/admin/apps       软件管理
/admin/publish    发布更新
/admin/history    版本历史
/admin/logs       下载日志
/admin/settings   系统设置

首次启动时也可以通过参数或环境变量设置初始密码:

$env:UPDATE_ADMIN_PASSWORD="你的初始密码"
hot-updater.exe -mode server

创建和发布软件

  1. 在“软件管理”中填写软件名称和唯一标识,例如名称 收银客户端、标识 cashier。
  2. 在“发布更新”中选择目标软件,填写版本号和独立更新说明,再上传要交付的文件。
  3. 新发布会成为该软件的当前版本。之前的版本、说明和文件不会删除,会出现在该软件的历史记录中并可单独下载。
  4. 每个软件有独立接口,例如 GET /api/version/cashier 和 GET /download/cashier。

发布文件不限制后缀,可以上传 exe、txt、zip、7z、lrj 或无后缀文件。服务端保留原文件名,客户端按 -output 指定的路径保存并替换文件。软件标识只能使用小写字母、数字、- 和 _,并且必须以字母或数字开头。单个发布文件最大 512 MiB。

多软件目录和发布历史保存在 -data-dir/catalog.json。旧版 release.json 会在首次启动时自动导入为标识 default 的“默认软件”;原文件和旧更新包保持不变。旧接口 /api/version 与 /download/update 继续指向默认软件。

管理端接口

GET/POST /api/version/{软件标识}              获取当前版本、更新说明、更新时间和历史日志
GET      /download/{软件标识}                 下载该软件的当前更新文件
GET      /download/{软件标识}/{版本记录 ID}   下载指定历史版本文件
GET/POST /api/version                         获取默认软件版本(兼容旧客户端)
GET      /download/update                     下载默认软件当前文件(兼容旧客户端)
GET      /health                              健康检查

GET /api/version/cashier 返回示例:

{
  "status": 1,
  "app_id": "cashier",
  "app_name": "收银客户端",
  "version": "1.2.0",
  "release_notes": "修复支付失败问题\n增加交班日志",
  "download_url": "/download/cashier",
  "direct_download_url": "http://updates.example.com/download/cashier",
  "file_name": "cashier.exe",
  "size": 171328,
  "updated_at": "2026-08-20T01:02:03Z",
  "history": [
    {
      "id": "1787190000000000000",
      "version": "1.2.0",
      "release_notes": "修复支付失败问题\n增加交班日志",
      "file_name": "cashier.exe",
      "size": 171328,
      "updated_at": "2026-08-20T01:02:03Z",
      "download_url": "/download/cashier/1787190000000000000",
      "direct_download_url": "http://updates.example.com/download/cashier/1787190000000000000"
    }
  ],
  "data": {
    "note_content": "1.2.0",
    "version": "1.2.0",
    "release_notes": "修复支付失败问题\n增加交班日志",
    "updated_at": "2026-08-20T01:02:03Z",
    "download_url": "/download/cashier",
    "direct_download_url": "http://updates.example.com/download/cashier"
  }
}

history 按新到旧排列,包含当前版本和所有历史版本。direct_download_url 是服务器根据当前请求协议和 Host 生成的绝对直连,可以直接交给下载器;原来的相对 download_url 保留用于兼容旧客户端。data.note_content 保留为版本号,用于兼容原来的 WebNote 客户端格式。

直连与下载日志

后台中的“复制直连”按钮只复制绝对下载地址,不会打开地址或触发下载。可以把这个地址直接发给其他人,或交给浏览器、下载器和脚本使用;访问当前版本或任一历史版本的直连时,服务端才会写入下载日志。

所有软件的下载记录统一追加到 -data-dir/download-logs.jsonl。每条记录包含请求时间、来源 IP、软件名称和标识、版本号、当前/历史分类、文件名、HTTP 状态、成功或失败、发送字节数、文件总大小、耗时、User-Agent 和错误信息。后台 /admin/logs 支持按软件模块切换,按成功/失败筛选,并按 IP、版本、文件名、状态码等关键词查询。

日志最多保留最近 10,000 条,单次页面最多显示最近 500 条匹配记录。日志文件与 catalog.json 一起放在数据目录中,服务重启后继续保留。

如果需要让其他设备访问,将监听地址改为 :8080,并给服务器配置防火墙、HTTPS 和强密码。

当前 Windows 电脑的 WLAN 属于 Public 网络,Go 程序没有入站防火墙权限。项目中的 lan-proxy.js 使用系统已有的 Node.js 入站规则,把 0.0.0.0:18084 透明转发到管理端 127.0.0.1:18083。双击 启动管理端.cmd 可以同时启动两者:

电脑管理页面:http://127.0.0.1:18083/admin/login
默认软件接口:http://本机局域网IP:18084/api/version
指定软件接口:http://本机局域网IP:18084/api/version/cashier

如果以管理员身份运行 允许热更新端口.ps1 开放 TCP 18083,则也可以直接使用 Go 服务,不经过 Node 转发。

2. 客户端检查更新

检查指定软件:

hot-updater.exe -mode client `
  -version 1.0 `
  -version-url http://127.0.0.1:8080/api/version/cashier `
  -output "cashier.exe"

管理端 API 会返回对应软件的下载地址,所以此时不需要填写 -download-url。客户端会显示远程版本、独立更新说明和更新时间。版本完全相同时不会下载;版本不一致时先下载到目标目录的临时文件,校验完成后再替换 -output。-output 可以是 exe、文本、压缩包、lrj 或其他任意目标文件。

客户端默认连接 http://127.0.0.1:8080/api/version。也兼容 WebNote 格式的版本接口和固定下载链接,但地址、笔记 ID 和下载地址必须显式提供:

hot-updater.exe -mode client `
  -version 1.0 `
  -version-url "https://你的版本服务/api" `
  -note-id "你的笔记ID" `
  -download-url "https://你的下载服务/update.bin" `
  -output "update.bin"

3. 懒人精灵 Lua 更新模块

仓库提供 examples/懒人精灵/更新模块.lua。它会在脚本启动时检查版本,下载并校验 .lrj 更新包,安装成功后重启脚本;检查或安装失败时会记录日志并继续执行当前脚本。

公开文件不包含任何默认服务器。加载模块前配置 _G.LR_UPDATE_CONFIG:

_G.LR_UPDATE_CONFIG = {
    serverBase = "https://你的更新服务器",
    appID = "你的软件标识",
    localVersionName = "1.0",
    timeoutSeconds = 8
}

local loaded, loadError = pcall(require, "更新模块")
if loaded and type(checkScriptUpdate) == "function" then
    pcall(checkScriptUpdate)
else
    print("更新模块加载失败:" .. tostring(loadError))
end

serverBase 不要包含末尾 /。版本接口使用 GET /api/version/{软件标识};更新包必须是 .lrj 文件。未配置服务器或更新失败不会阻止原脚本继续运行。

常用参数

-mode            client 或 server,默认 client
-version         客户端当前版本,默认 1.0
-version-url     指定软件的版本检查 API 地址
-download-url    API 没返回下载地址时使用的固定下载地址
-output          客户端保存路径,默认 zf注册.lrj
-retries         版本检查重试次数,默认 3
-retry-delay     重试间隔,默认 1s
-timeout         单次 HTTP 请求超时,默认 30s
-listen          管理端监听地址,默认 127.0.0.1:8080
-data-dir        管理端数据目录,默认 update-data
-admin-user      管理员用户名,默认 admin
-admin-password  首次启动时的管理员密码,也可用 UPDATE_ADMIN_PASSWORD 设置

编译与测试

go test ./...
go vet ./...

Windows x64:

$env:GOOS="windows"
$env:GOARCH="amd64"
go build -o dist/hot-updater-windows-amd64.exe .

Linux x64:

$env:GOOS="linux"
$env:GOARCH="amd64"
go build -o dist/hot-updater-linux-amd64 .

License

MIT

About

懒人精灵等脚本语言热更新

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages