diff --git a/lib/agent.dart b/lib/agent.dart index 58059bc..d654d2b 100644 --- a/lib/agent.dart +++ b/lib/agent.dart @@ -4,6 +4,7 @@ import 'print/backend.dart'; import 'print/mock_backend.dart'; import 'server/http_server.dart'; import 'server/print_queue.dart'; +import 'build_info.g.dart'; import 'utils/file_log.dart'; /// 启动参数:--mock 模拟打印;--port=NNN / --port NNN 指定监听端口(默认 38200-38202 顺延)。 @@ -73,10 +74,11 @@ class Agent { backend: backend, mock: options.mock, manifestBackendName: backendName, + appVersion: kBuildVersion, ); final ports = options.port == null ? const [38200, 38201, 38202] : [options.port!]; port = await server.start(candidatePorts: ports); - log.write('资安信插件助手已启动 http://127.0.0.1:$port' + log.write('资安信插件助手 v$kBuildVersion 已启动 http://127.0.0.1:$port' '(后端=$backendName,mock=${options.mock},agent=desktop-plugin)'); return port!; } diff --git a/lib/build_info.g.dart b/lib/build_info.g.dart new file mode 100644 index 0000000..3b13416 --- /dev/null +++ b/lib/build_info.g.dart @@ -0,0 +1,3 @@ +// 由打包脚本自动生成(tool/package_windows.ps1 / tool/package_macos.sh),勿手改。 +// 手动 flutter build 未跑脚本时保持上次打包的值;脚本打包会写入"版本+git提交+时间"。 +const String kBuildVersion = 'dev'; diff --git a/lib/server/http_server.dart b/lib/server/http_server.dart index 38d708a..ef47ae6 100644 --- a/lib/server/http_server.dart +++ b/lib/server/http_server.dart @@ -16,6 +16,7 @@ class AgentHttpServer { required this.backend, required this.mock, required this.manifestBackendName, + this.appVersion = '', this.agentName = 'desktop-plugin', }); @@ -27,6 +28,9 @@ class AgentHttpServer { /// manifest 里的 backend 字段按操作系统报(pavo/cups),与是否 mock 无关(对齐 C# 版) final String manifestBackendName; + + /// 构建版本(打包脚本注入),随 manifest 暴露给前端核对 + final String appVersion; final String agentName; HttpServer? _server; @@ -65,6 +69,7 @@ class AgentHttpServer { ..get('/manifest', (Request r) => _ok({ 'plugins': [ManifestPlugin().toJson()], 'agent': agentName, + 'version': appVersion, 'backend': manifestBackendName, 'mock': mock, })) diff --git a/lib/ui/card_printer_page.dart b/lib/ui/card_printer_page.dart index 4a3e1ed..c5d389a 100644 --- a/lib/ui/card_printer_page.dart +++ b/lib/ui/card_printer_page.dart @@ -3,6 +3,8 @@ import 'dart:io'; import 'package:flutter/material.dart'; +import '../build_info.g.dart'; + import '../agent.dart'; import '../server/protocol.dart'; import '../utils/file_log.dart'; @@ -121,6 +123,14 @@ class _CardPrinterPageState extends State { .bodyMedium ?.copyWith(color: scheme.onSurfaceVariant), ), + const SizedBox(height: 2), + Text( + '版本 $kBuildVersion', + style: Theme.of(context) + .textTheme + .labelSmall + ?.copyWith(color: scheme.onSurfaceVariant.withValues(alpha: 0.7)), + ), ], ), ), diff --git a/tool/package_macos.sh b/tool/package_macos.sh index c7a461e..0a3c06f 100755 --- a/tool/package_macos.sh +++ b/tool/package_macos.sh @@ -7,7 +7,14 @@ cd "$(dirname "$0")/.." APP_NAME="资安信插件助手" APP="build/macos/Build/Products/Release/${APP_NAME}.app" -DMG="dist/${APP_NAME}-macOS.dmg" + +# 版本号 = 1.0..,写入 build_info.g.dart 并用于 dmg 文件名 +GIT_HASH=$(git rev-parse --short HEAD 2>/dev/null || echo nogit) +STAMP=$(date +%m%d.%H%M) +VERSION="1.0.${STAMP}.${GIT_HASH}" +printf '// 由打包脚本自动生成(tool/package_windows.ps1 / tool/package_macos.sh),勿手改。\n// 手动 flutter build 未跑脚本时保持上次打包的值;脚本打包会写入"版本+git提交+时间"。\nconst String kBuildVersion = '"'"'%s'"'"';\n' "$VERSION" > lib/build_info.g.dart +DMG="dist/${APP_NAME}-macOS-${VERSION}.dmg" +echo "==> 版本号:$VERSION" echo "==> flutter build macos --release" flutter build macos --release diff --git a/tool/package_windows.ps1 b/tool/package_windows.ps1 new file mode 100644 index 0000000..35beeeb --- /dev/null +++ b/tool/package_windows.ps1 @@ -0,0 +1,59 @@ +# 资安信插件助手 Windows 一键打包脚本(版本号自动注入) +# 用法:在项目根目录执行 powershell -ExecutionPolicy Bypass -File tool\package_windows.ps1 +# 产物:dist\资安信插件助手-windows-setup-<版本>.exe +# 版本格式:1.0..,同时写入: +# - lib\build_info.g.dart(App 内/manifest/启动日志可见) +# - 安装包文件名(一眼区分新旧包) +param( + [string]$InnoPath = "$env:LOCALAPPDATA\Programs\Inno Setup 6\ISCC.exe" +) + +$ErrorActionPreference = 'Stop' +Set-Location (Join-Path $PSScriptRoot '..') + +# ---- 1. 计算版本 ---- +$gitHash = (git rev-parse --short HEAD).Trim() +if (-not $gitHash) { $gitHash = 'nogit' } +$stamp = Get-Date -Format 'MMdd.HHmm' +$version = "1.0.$stamp.$gitHash" + +# ---- 2. 写入版本文件(UTF-8 无 BOM,Dart 兼容) ---- +$dartContent = @" +// 由打包脚本自动生成(tool/package_windows.ps1 / tool/package_macos.sh),勿手改。 +// 手动 flutter build 未跑脚本时保持上次打包的值;脚本打包会写入"版本+git提交+时间"。 +const String kBuildVersion = '$version'; +"@ +[System.IO.File]::WriteAllText( + (Join-Path (Get-Location) 'lib\build_info.g.dart'), + $dartContent, + (New-Object System.Text.UTF8Encoding($false)) +) +Write-Host "==> 版本号:$version(git=$gitHash)" + +# ---- 3. flutter 构建 ---- +Write-Host '==> flutter build windows --release' +flutter build windows --release +if ($LASTEXITCODE -ne 0) { throw 'flutter build 失败' } + +# ---- 4. 定位 ISCC ---- +if (-not (Test-Path $InnoPath)) { + $candidates = @( + 'C:\Program Files (x86)\Inno Setup 6\ISCC.exe', + 'C:\Program Files\Inno Setup 6\ISCC.exe' + ) + $InnoPath = $candidates | Where-Object { Test-Path $_ } | Select-Object -First 1 +} +if (-not $InnoPath) { throw "未找到 Inno Setup(ISCC.exe)。请安装 Inno 6:https://jrsoftware.org/isdl.php" } + +# ---- 5. Inno 编译(带版本号注入安装包文件名) ---- +Write-Host "==> iscc /DAppVersionFull=$version" +& $InnoPath "/DAppVersionFull=$version" 'windows\installer.iss' +if ($LASTEXITCODE -ne 0) { throw 'iscc 编译失败' } + +# ---- 6. 收尾提示 ---- +$out = "dist\资安信插件助手-windows-setup-$version.exe" +Write-Host '' +Write-Host '==> 打包完成' +if (Test-Path $out) { Get-Item $out | Select-Object Name, Length, LastWriteTime | Format-List } +Write-Host '提醒:安装新版前,先退出右下角托盘里旧版"资安信插件助手"(否则 38200 被旧实例占用,浏览器仍连旧版)。' +Write-Host '验证:安装后浏览器打开 http://127.0.0.1:38200/manifest ,version 字段应为:' $version diff --git a/windows/installer.iss b/windows/installer.iss index be703e5..5b0f026 100644 --- a/windows/installer.iss +++ b/windows/installer.iss @@ -4,19 +4,24 @@ ; 产物:dist\资安信插件助手-windows-setup.exe #define AppName "资安信插件助手" +; AppVersionFull 由打包脚本(tool/package_windows.ps1)以 /DAppVersionFull=... 注入; +; 手动 iscc 时无该定义则回落到固定号 +#ifndef AppVersionFull +#define AppVersionFull "1.0.0-dev" +#endif #define AppVersion "1.0.0" #define AppExeName "desktop_plugin.exe" [Setup] AppId={{8C5B7A42-1F2D-4E6B-9A71-9D3A0F2C7E51} AppName={#AppName} -AppVersion={#AppVersion} +AppVersion={#AppVersionFull} AppPublisher=zax DefaultDirName={autopf}\{#AppName} DefaultGroupName={#AppName} UninstallDisplayIcon={app}\{#AppExeName} OutputDir=..\dist -OutputBaseFilename=资安信插件助手-windows-setup +OutputBaseFilename=资安信插件助手-windows-setup-{#AppVersionFull} ; x64compatible 需 Inno 6.3+;x64 全系 6.x 兼容 ; x64compatible 为 Inno 6.3+ 推荐写法(6.7 上用 x64 会报 deprecation 警告) ArchitecturesInstallIn64BitMode=x64compatible