发布链路概述

OTA 桌面工具从源码到安装包,经过三个环节:

dotnet publish → Authenticode 签名 → Inno Setup 打包 → 签名安装包

全部由 PowerShell 脚本 Build-SignedOtaRelease.ps1 一键完成。

第一步:dotnet publish

发布目标为 OTA.UI 项目,使用 -p:PublishSingleFile=true 生成自包含单文件,无需用户预装 .NET Runtime:

dotnet publish OTA\OTA.UI\OTA.UI.csproj `
  -c Release `
  -r win-x64 `
  -p:PublishSingleFile=true `
  -p:SelfContained=true `
  -p:IncludeNativeLibrariesForSelfExtract=true `
  -o Deploy\Artifacts\OTA

输出产物只有 OTA.exe 一个文件,包含所有托管代码和原生运行时,直接复制即可运行。

第二步:Authenticode 代码签名

使用本地 PFX 证书对 OTA.exe 做 Authenticode 签名:

signtool sign /fd sha256 /f $PfxPath /p $PfxPassword `
  /tr http://timestamp.digicert.com /td sha256 `
  /v $ExePath

关键参数:

参数说明
/fd sha256文件摘要算法
/fPFX 证书路径
/pPFX 密码(从环境变量 MILL_CODE_SIGN_PFX_PASSWORD 读取)
/trRFC 3161 时间戳服务器 URL
/td sha256时间戳摘要算法

签名后验证:

signtool verify /pa /tw $ExePath
Get-AuthenticodeSignature $ExePath

/pa 验证是否符合 Windows 驱动签名策略,/tw 检查时间戳从而判断即使证书过期签名是否仍然有效。

第三步:Inno Setup 打包

使用 Inno Setup 6 和 Mill_Installer.iss 脚本生成安装包。

安装器基本信息

属性
应用名磨坊系统升级工具
版本2.1.0
发布者zhiqiangme
GUID{4535FFBB-EB5D-4D28-BF6A-BC7796C8C8B8}
安装路径%ProgramFiles%\zhiqiangme\Mill
权限要求管理员(需要静默安装 .NET Runtime)
压缩LZMA2 固实压缩
架构x64 专用

文件部署

阶段来源目标说明
搬运 OTAArtifacts\OTA\OTA.exe{app}\OTA.exe自包含单文件
可选 RuntimeDrivers\windowsdesktop-runtime-10.0.8-win-x64.exe{tmp}\临时目录,安装后删除

可选组件:.NET Runtime 静默安装

Inno Setup 提供”安装 .NET Desktop Runtime 10.0.8 x64”复选框,首次进入任务页时自动检测并勾选缺失的 Runtime。

检测逻辑优先级:

  1. 检查 %ProgramFiles%\dotnet\shared\Microsoft.WindowsDesktop.App\10.* 目录是否存在
  2. 回退检查注册表 HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedfx\Microsoft.WindowsDesktop.App

安装使用 windowsdesktop-runtime-10.0.8-win-x64.exe /install /quiet /norestart,安装后轮询最多 20 秒确认 Runtime 已就位。如果安装器返回成功但 Runtime 仍未被检测到,再用 /repair 参数修复一次。安装日志写入 {app}\install-logs\

退出码处理:0=成功,3010=需要重启,1641=已请求重启,三者均视为成功。

快捷方式

  • 开始菜单:磨坊系统升级工具.lnk
  • 桌面(可选):磨坊系统升级工具.lnk
  • 安装完成后自动启动 OTA.exe

第四步:安装包签名

打包完成后,对安装包 EXE 也做 Authenticode 签名,确保用户下载安装包时 Windows SmartScreen 不会报毒。

发布脚本

# 完整发布(发布 + 签名 + 打包 + 签名 + 验证)
.\Deploy\Build-SignedOtaRelease.ps1

# 跳过发布(复用已有 OTA.exe,仅签名 + 打包)
.\Deploy\Build-SignedOtaRelease.ps1 -SkipPublish

输出产物在 Deploy\Output\ 目录:

磨坊系统升级工具_安装包_v2.1.0.exe

安全约定

规则原因
PFX 密码不写入脚本/README/Git避免凭证泄露
PFX 路径不在脚本中硬编码允许不同机器使用不同路径
密码通过环境变量 MILL_CODE_SIGN_PFX_PASSWORD 传递只在当前会话可见
Deploy\Keys\Artifacts\Output\ 加入 .gitignore不提交证书和发布产物
时间戳服务器 timestamp.digicert.com证书过期后签名仍有效

构建命令

cd D:\Project\Mill
$env:MILL_CODE_SIGN_PFX_PASSWORD = "你的PFX密码"
.\Deploy\Build-SignedOtaRelease.ps1

与固件签名的关系

本文描述的代码签名仅针对 Windows 桌面程序(.exe)。固件镜像(App_A.bin / App_B.bin)的 ECDSA 签名由 OTA 软件运行时的固件签名链路处理,属于不同的签名体系,不在此发布流程中。