补充打包方式
This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
; 年糕历险记 —— Windows 安装脚本(NSIS 3,简体中文)
|
||||
; 用法:makensis /DVERSION=1.0.0 scripts/installer.nsi
|
||||
; 产物:年糕历险记-Setup-v1.0.0.exe(构建与发布.md §8)
|
||||
; 特性:简体中文向导、可选安装目录、
|
||||
; 快捷方式选项(组件页:桌面 / 开始菜单,默认勾选)、
|
||||
; 安装完成后可选立即运行(完成页,默认勾选)、开始菜单卸载、卸载保留存档。
|
||||
|
||||
!include "MUI2.nsh"
|
||||
|
||||
@@ -24,12 +27,27 @@ InstallDirRegKey HKCU "${UNINSTALL_KEY}" "InstallLocation"
|
||||
RequestExecutionLevel user
|
||||
SetCompressor /SOLID lzma
|
||||
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_FINISHPAGE_RUN "$INSTDIR\${PRODUCT_EXE}"
|
||||
!define MUI_FINISHPAGE_RUN_TEXT "运行${PRODUCT_NAME}"
|
||||
; 安装器 exe 自身的版本信息
|
||||
VIProductVersion "${VERSION}.0"
|
||||
VIAddVersionKey "ProductName" "${PRODUCT_NAME}"
|
||||
VIAddVersionKey "FileDescription" "${PRODUCT_NAME} 安装程序"
|
||||
VIAddVersionKey "FileVersion" "${VERSION}"
|
||||
VIAddVersionKey "ProductVersion" "${VERSION}"
|
||||
VIAddVersionKey "CompanyName" "${PRODUCT_PUBLISHER}"
|
||||
VIAddVersionKey "LegalCopyright" "Copyright (C) ${PRODUCT_PUBLISHER}"
|
||||
|
||||
; ---- 页面(全中文)----
|
||||
!define MUI_ABORTWARNING
|
||||
; 安装器/卸载器图标:游戏 logo(make_icon.ps1 从素材包 pack.png 生成多尺寸 icon.ico,
|
||||
; 构建与发布.md §8「安装器图标」规范:安装包必须与游戏本体同图标)
|
||||
!define MUI_ICON "..\cmd\client\icon.ico"
|
||||
!define MUI_UNICON "..\cmd\client\icon.ico"
|
||||
; 完成页「安装完成后运行」复选框(默认勾选)
|
||||
!define MUI_FINISHPAGE_RUN "$INSTDIR\${PRODUCT_EXE}"
|
||||
!define MUI_FINISHPAGE_RUN_TEXT "安装完成后运行${PRODUCT_NAME}"
|
||||
|
||||
; ---- 页面(全中文):欢迎 → 组件(快捷方式选项)→ 目录 → 安装 → 完成 ----
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_COMPONENTS
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
@@ -41,6 +59,7 @@ SetCompressor /SOLID lzma
|
||||
|
||||
; ---- 安装内容(构建与发布.md §8)----
|
||||
Section "主程序" SEC01
|
||||
SectionIn RO
|
||||
SetOutPath "$INSTDIR"
|
||||
File "..\bin\mc-client.exe"
|
||||
File "..\bin\mc-server.exe"
|
||||
@@ -80,15 +99,21 @@ Section "主程序" SEC01
|
||||
WriteRegDWORD HKCU "${UNINSTALL_KEY}" "NoRepair" 1
|
||||
|
||||
WriteUninstaller "$INSTDIR\uninstall.exe"
|
||||
SectionEnd
|
||||
|
||||
; 快捷方式(桌面 + 开始菜单,中文名)
|
||||
; 快捷方式选项 1:桌面(默认勾选)
|
||||
Section "创建桌面快捷方式" SEC02
|
||||
CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_EXE}"
|
||||
SectionEnd
|
||||
|
||||
; 快捷方式选项 2:开始菜单(默认勾选)
|
||||
Section "创建开始菜单快捷方式" SEC03
|
||||
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
|
||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_EXE}"
|
||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\卸载${PRODUCT_NAME}.lnk" "$INSTDIR\uninstall.exe"
|
||||
SectionEnd
|
||||
|
||||
; ---- 卸载 ----
|
||||
; ---- 卸载(保留用户存档 worlds/ 与日志)----
|
||||
Section "Uninstall"
|
||||
Delete "$DESKTOP\${PRODUCT_NAME}.lnk"
|
||||
RMDir /r "$SMPROGRAMS\${PRODUCT_NAME}"
|
||||
@@ -101,3 +126,10 @@ Section "Uninstall"
|
||||
; 保留用户存档(worlds/)与日志,不删除
|
||||
DeleteRegKey HKCU "${UNINSTALL_KEY}"
|
||||
SectionEnd
|
||||
|
||||
; ---- 组件说明(组件页底部;必须放在所有 Section 声明之后)----
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC01} "安装游戏主程序(客户端、服务器、素材包与配置文件)。必选。"
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC02} "在桌面创建「${PRODUCT_NAME}」快捷方式。"
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC03} "在开始菜单创建「${PRODUCT_NAME}」与「卸载${PRODUCT_NAME}」快捷方式。"
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 年糕历险记 —— 程序图标生成(构建与发布.md §8:exe/窗口使用原版素材 logo)
|
||||
# 年糕历险记 —— 程序图标生成(构建与发布.md §8:exe/窗口/快捷方式/安装器使用原版素材 logo)
|
||||
# 用法:pwsh -File scripts/make_icon.ps1
|
||||
# 流程:素材包 pack.png → cmd/client/icon.png → go-winres 生成 cmd/client/icon.syso
|
||||
# (资源目录树格式,Go 链接器自动嵌入 exe;资源管理器/任务栏/快捷方式显示图标)。
|
||||
# 流程:素材包 pack.png → cmd/client/icon.png → go-winres 生成 icon.syso(嵌入游戏 exe)
|
||||
# → 同时生成多尺寸 cmd/client/icon.ico(供 NSIS 安装器 MUI_ICON / MUI_UNICON 使用)
|
||||
$ErrorActionPreference = "Stop"
|
||||
$root = Split-Path $PSScriptRoot -Parent
|
||||
|
||||
@@ -20,9 +20,47 @@ $env:GOCACHE = Join-Path $root ".gocache"
|
||||
Push-Location (Join-Path $root "cmd\client")
|
||||
try {
|
||||
go run github.com/tc-hib/go-winres@latest make --in winres.json --out icon --arch amd64 --no-suffix
|
||||
if ($LASTEXITCODE -ne 0) { throw "go-winres 生成失败" }
|
||||
if ($LASTEXITCODE -ne 0) { throw "go-winres 生成失败" }
|
||||
Move-Item -Force (Join-Path (Get-Location) "icon") (Join-Path (Get-Location) "icon.syso")
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
Write-Host "== 图标资源已嵌入:cmd/client/icon.syso =="
|
||||
Write-Host "== 图标资源已嵌入:cmd/client/icon.syso =="
|
||||
|
||||
# 3) 生成多尺寸 icon.ico(16/24/32/48/64/128/256,PNG 压缩,供 NSIS 安装器/卸载器使用)
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
$src = [System.Drawing.Image]::FromFile((Join-Path $root "cmd\client\icon.png"))
|
||||
$sizes = @(16, 24, 32, 48, 64, 128, 256)
|
||||
$ms = New-Object System.IO.MemoryStream
|
||||
$bw = New-Object System.IO.BinaryWriter($ms)
|
||||
# ICONDIR:reserved(2)=0, type(2)=1, count(2)
|
||||
$bw.Write([uint16]0); $bw.Write([uint16]1); $bw.Write([uint16]$sizes.Count)
|
||||
$offset = 6 + 16 * $sizes.Count
|
||||
$images = @()
|
||||
foreach ($s in $sizes) {
|
||||
$bmp = New-Object System.Drawing.Bitmap($s, $s)
|
||||
$g = [System.Drawing.Graphics]::FromImage($bmp)
|
||||
$g.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
|
||||
$g.DrawImage($src, 0, 0, $s, $s)
|
||||
$g.Dispose()
|
||||
$pngMs = New-Object System.IO.MemoryStream
|
||||
$bmp.Save($pngMs, [System.Drawing.Imaging.ImageFormat]::Png)
|
||||
$images += ,$pngMs.ToArray()
|
||||
$bmp.Dispose(); $pngMs.Dispose()
|
||||
}
|
||||
for ($i = 0; $i -lt $sizes.Count; $i++) {
|
||||
$s = $sizes[$i]
|
||||
$dim = if ($s -ge 256) { 0 } else { $s } # 256 用 0 表示
|
||||
$bw.Write([byte]$dim); $bw.Write([byte]$dim)
|
||||
$bw.Write([byte]0); $bw.Write([byte]0) # colors / reserved
|
||||
$bw.Write([uint16]1); $bw.Write([uint16]32) # planes / bpp
|
||||
$bw.Write([uint32]$images[$i].Length)
|
||||
$bw.Write([uint32]$offset)
|
||||
$offset += $images[$i].Length
|
||||
}
|
||||
foreach ($d in $images) { $bw.Write($d) }
|
||||
$bw.Flush()
|
||||
[System.IO.File]::WriteAllBytes((Join-Path $root "cmd\client\icon.ico"), $ms.ToArray())
|
||||
$src.Dispose()
|
||||
$bw.Close(); $ms.Dispose()
|
||||
Write-Host "== 安装器图标已生成:cmd/client/icon.ico($($sizes -join '/') px)=="
|
||||
|
||||
48
scripts/make_nsis.ps1
Normal file
48
scripts/make_nsis.ps1
Normal file
@@ -0,0 +1,48 @@
|
||||
# 年糕历险记 —— NSIS 正式安装器构建脚本(构建与发布.md §8 交付方案)
|
||||
# 用法:pwsh -File scripts/make_nsis.ps1 [-Version 0.1.0]
|
||||
# 前置:C 工具链(tools/ 下 zig 或 MinGW,构建 GL 客户端需要);
|
||||
# NSIS 3(自动查找 tools/nsis/nsis-*/makensis.exe,其次 PATH 中的 makensis)
|
||||
# 产物:dist/年糕历险记-Setup-v<版本>.exe(简体中文向导、快捷方式选项、完成页运行选项)
|
||||
param([string]$Version = "0.1.0")
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$root = Split-Path $PSScriptRoot -Parent
|
||||
|
||||
# 1) 构建 bin/(复用 build.ps1:定位 zig/gcc,产出 mc-client.exe / mc-server.exe 及资源)
|
||||
& (Join-Path $PSScriptRoot "build.ps1")
|
||||
if ($LASTEXITCODE -ne 0) { throw "构建失败(build.ps1)" }
|
||||
|
||||
# 2) 定位 makensis:优先 tools/nsis/(本项目自带 NSIS 3.10),其次系统 PATH
|
||||
$makensisPath = (Get-ChildItem (Join-Path $root "tools\nsis") -Recurse -Filter makensis.exe -ErrorAction SilentlyContinue | Select-Object -First 1).FullName
|
||||
if (-not $makensisPath) {
|
||||
$cmd = Get-Command makensis -ErrorAction SilentlyContinue
|
||||
if ($cmd) { $makensisPath = $cmd.Source }
|
||||
}
|
||||
if (-not $makensisPath) {
|
||||
throw "未找到 NSIS:请把 NSIS 3 放到 tools/nsis/(如 nsis-3.10)或加入 PATH。下载:https://nsis.sourceforge.io/Download"
|
||||
}
|
||||
|
||||
# 3) 确保安装器图标存在(游戏 logo:make_icon.ps1 生成 icon.syso 与 icon.ico;
|
||||
# 缺失时调用;规范见 构建与发布.md §8「安装器图标」)
|
||||
if (-not (Test-Path (Join-Path $root "cmd\client\icon.ico"))) {
|
||||
& (Join-Path $PSScriptRoot "make_icon.ps1")
|
||||
if ($LASTEXITCODE -ne 0) { throw "图标生成失败(make_icon.ps1)" }
|
||||
}
|
||||
|
||||
# 3) 编译安装器(中文界面、快捷方式选项、安装完成后运行选项)
|
||||
# installer.nsi 需为 UTF-8 带 BOM(NSIS 3 按 BOM 识别编码;文本编辑器保存可能去掉 BOM,这里自动补回)
|
||||
$nsi = Join-Path $PSScriptRoot "installer.nsi"
|
||||
$nsiBytes = [System.IO.File]::ReadAllBytes($nsi)
|
||||
if (-not ($nsiBytes.Length -ge 3 -and $nsiBytes[0] -eq 0xEF -and $nsiBytes[1] -eq 0xBB -and $nsiBytes[2] -eq 0xBF)) {
|
||||
[System.IO.File]::WriteAllText($nsi, [System.IO.File]::ReadAllText($nsi), (New-Object System.Text.UTF8Encoding($true)))
|
||||
Write-Host "== installer.nsi 已补 UTF-8 BOM =="
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Force -Path (Join-Path $root "dist") | Out-Null
|
||||
& $makensisPath "/DVERSION=$Version" $nsi
|
||||
if ($LASTEXITCODE -ne 0) { throw "makensis 编译失败" }
|
||||
|
||||
$exe = Join-Path $root "dist\年糕历险记-Setup-v$Version.exe"
|
||||
if (-not (Test-Path $exe)) { throw "未找到安装器产物:$exe" }
|
||||
$sizeMB = [math]::Round((Get-Item $exe).Length / 1MB, 1)
|
||||
Write-Host "== NSIS 安装器就绪:$exe($sizeMB MB)=="
|
||||
Reference in New Issue
Block a user