发布链路概述
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 | 文件摘要算法 |
/f | PFX 证书路径 |
/p | PFX 密码(从环境变量 MILL_CODE_SIGN_PFX_PASSWORD 读取) |
/tr | RFC 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 专用 |
文件部署
| 阶段 | 来源 | 目标 | 说明 |
|---|---|---|---|
| 搬运 OTA | Artifacts\OTA\OTA.exe | {app}\OTA.exe | 自包含单文件 |
| 可选 Runtime | Drivers\windowsdesktop-runtime-10.0.8-win-x64.exe | {tmp}\ | 临时目录,安装后删除 |
可选组件:.NET Runtime 静默安装
Inno Setup 提供”安装 .NET Desktop Runtime 10.0.8 x64”复选框,首次进入任务页时自动检测并勾选缺失的 Runtime。
检测逻辑优先级:
- 检查
%ProgramFiles%\dotnet\shared\Microsoft.WindowsDesktop.App\10.*目录是否存在 - 回退检查注册表
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 软件运行时的固件签名链路处理,属于不同的签名体系,不在此发布流程中。