chore(build): 更新.gitignore配置和清理Wails临时文件
- 添加dist/目录到.gitignore,用于排除打包输出的绿色免安装版 - 添加Wails打包过程中的临时文件和自动生成文件到.gitignore - 删除build/windows/installer/wails_tools.nsh自动生成文件 - 添加Windows安装器临时目录和Webview2安装文件到忽略列表 feat(docs): 添加万川平台对接文档和产品素材 - 创建万川平台登录到获取模型信息的流程说明文档 - 添加万川平台对接实施计划文档 - 新增产品图片、公司简介图、宣传海报、教程截图、案例展示等素材文件 refactor(runtime): 扩展通知功能类型定义 - 添加NotificationOptions接口定义 - 添加NotificationAction接口定义 - 添加NotificationCategory接口定义 - 扩展通知相关的运行时API类型声明,包括初始化、发送、注册分类等功能
This commit is contained in:
209
scripts/build.ps1
Normal file
209
scripts/build.ps1
Normal file
@@ -0,0 +1,209 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
一键打包脚本。
|
||||
|
||||
.DESCRIPTION
|
||||
默认产出「绿色免安装版」到 dist\qiweimanager\(不需要 NSIS,解压即用):
|
||||
1. 定位 Go / Wails 工具链并注入 PATH。
|
||||
2. 32 位编译 helper.exe;编译 silk 音频解码器。
|
||||
3. wails build 生成主程序 qiweimanager.exe(前端一并编译)。
|
||||
4. 汇总主程序 + helper + DLL + 工具 + 默认配置到 dist 目录。
|
||||
|
||||
指定 -Installer 时,额外调用现有的 scripts\package-windows.ps1 走 NSIS 生成安装包
|
||||
(需本机已安装 NSIS)。
|
||||
|
||||
.PARAMETER Installer
|
||||
额外生成 NSIS 安装包(委托 package-windows.ps1,需要 makensis)。
|
||||
|
||||
.PARAMETER SkipTests
|
||||
跳过 go test。
|
||||
|
||||
.PARAMETER GoPath / WailsPath
|
||||
手动指定工具路径(自动探测失败时使用)。
|
||||
|
||||
.EXAMPLE
|
||||
powershell -ExecutionPolicy Bypass -File scripts\build.ps1
|
||||
powershell -ExecutionPolicy Bypass -File scripts\build.ps1 -Installer
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[switch]$Installer,
|
||||
[switch]$SkipTests,
|
||||
[string]$GoPath,
|
||||
[string]$WailsPath
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$repoRoot = (Resolve-Path (Join-Path $scriptDir "..")).Path
|
||||
Set-Location $repoRoot
|
||||
|
||||
function Write-Step([string]$msg) { Write-Host "==> $msg" -ForegroundColor Cyan }
|
||||
function Write-Ok([string]$msg) { Write-Host " $msg" -ForegroundColor Green }
|
||||
function Write-Warn2([string]$msg){ Write-Host " $msg" -ForegroundColor Yellow }
|
||||
|
||||
function Resolve-Go {
|
||||
param([string]$Hint)
|
||||
$candidates = @()
|
||||
if ($Hint) { $candidates += $Hint }
|
||||
$cmd = Get-Command go.exe -ErrorAction SilentlyContinue
|
||||
if ($cmd) { $candidates += $cmd.Source }
|
||||
$candidates += "$env:LOCALAPPDATA\Programs\Go\bin\go.exe", "C:\Program Files\Go\bin\go.exe", "C:\Go\bin\go.exe"
|
||||
foreach ($c in $candidates) { if ($c -and (Test-Path $c)) { return (Resolve-Path $c).Path } }
|
||||
throw "未找到 Go。请安装 Go 1.24+ 后重试,或用 -GoPath 指定。"
|
||||
}
|
||||
|
||||
function Resolve-Wails {
|
||||
param([string]$Hint)
|
||||
$candidates = @()
|
||||
if ($Hint) { $candidates += $Hint }
|
||||
$cmd = Get-Command wails.exe -ErrorAction SilentlyContinue
|
||||
if ($cmd) { $candidates += $cmd.Source }
|
||||
$candidates += "$env:USERPROFILE\go\bin\wails.exe"
|
||||
foreach ($c in $candidates) { if ($c -and (Test-Path $c)) { return (Resolve-Path $c).Path } }
|
||||
throw "未找到 Wails CLI。请先运行 scripts\dev.ps1 安装,或用 -WailsPath 指定。"
|
||||
}
|
||||
|
||||
function Copy-Required {
|
||||
param([string]$Source, [string]$Destination)
|
||||
if (-not (Test-Path -LiteralPath $Source)) { throw "缺少资源: $Source" }
|
||||
$dir = Split-Path -Parent $Destination
|
||||
if ($dir -and -not (Test-Path -LiteralPath $dir)) { New-Item -ItemType Directory -Force -Path $dir | Out-Null }
|
||||
Copy-Item -LiteralPath $Source -Destination $Destination -Force
|
||||
}
|
||||
|
||||
# ---- 委托 NSIS 安装包构建 ----
|
||||
if ($Installer) {
|
||||
Write-Step "委托 package-windows.ps1 生成 NSIS 安装包"
|
||||
$pkg = Join-Path $scriptDir "package-windows.ps1"
|
||||
$pkgArgs = @{}
|
||||
if ($SkipTests) { $pkgArgs["SkipTests"] = $true }
|
||||
if ($WailsPath) { $pkgArgs["WailsPath"] = $WailsPath }
|
||||
& $pkg @pkgArgs
|
||||
return
|
||||
}
|
||||
|
||||
# ---- 工具链 ----
|
||||
Write-Step "定位 Go / Wails 工具链"
|
||||
$go = Resolve-Go -Hint $GoPath
|
||||
$goBin = Split-Path -Parent $go
|
||||
$env:PATH = "$goBin;$env:USERPROFILE\go\bin;$env:PATH"
|
||||
$wails = Resolve-Wails -Hint $WailsPath
|
||||
Write-Ok "Go: $go"
|
||||
Write-Ok "Wails: $wails"
|
||||
|
||||
$goCache = Join-Path $repoRoot ".gocache"
|
||||
New-Item -ItemType Directory -Force -Path $goCache | Out-Null
|
||||
$env:GOCACHE = $goCache
|
||||
|
||||
$binDir = Join-Path $repoRoot "build\bin"
|
||||
$distDir = Join-Path $repoRoot "dist\qiweimanager"
|
||||
|
||||
# ---- 测试 ----
|
||||
if (-not $SkipTests) {
|
||||
Write-Step "运行 Go 测试 (go test ./...)"
|
||||
& $go test ./...
|
||||
Write-Ok "测试通过"
|
||||
}
|
||||
|
||||
# ---- 结束运行中的旧进程,避免覆盖失败 ----
|
||||
$running = Get-Process -Name "qiweimanager", "qiweimanager-dev", "helper", "helper_auto_reply" -ErrorAction SilentlyContinue
|
||||
foreach ($p in $running) { Write-Warn2 "结束运行中的进程: $($p.ProcessName) ($($p.Id))"; Stop-Process -Id $p.Id -Force }
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $binDir | Out-Null
|
||||
|
||||
# ---- 32 位 helper.exe ----
|
||||
Write-Step "编译 32 位 helper.exe"
|
||||
$helperOut = Join-Path $binDir "helper.exe"
|
||||
$oldArch = $env:GOARCH
|
||||
try {
|
||||
$env:GOARCH = "386"
|
||||
Push-Location (Join-Path $repoRoot "helper")
|
||||
& $go build -trimpath -ldflags "-H windowsgui -s -w" -o $helperOut .
|
||||
if ($LASTEXITCODE -ne 0) { throw "helper.exe 编译失败 (exit $LASTEXITCODE)" }
|
||||
} finally {
|
||||
Pop-Location
|
||||
if ($null -eq $oldArch) { Remove-Item Env:GOARCH -ErrorAction SilentlyContinue } else { $env:GOARCH = $oldArch }
|
||||
}
|
||||
Write-Ok "helper.exe 完成"
|
||||
|
||||
# ---- silk 音频解码器(尽力而为,需要 cgo/gcc;缺失则跳过,仅影响语音消息转码)----
|
||||
Write-Step "编译 silk 音频解码器"
|
||||
$silkOut = Join-Path $binDir "tools\audio\silkdecode.exe"
|
||||
$silkBuilt = $false
|
||||
$hasGcc = [bool](Get-Command gcc -ErrorAction SilentlyContinue)
|
||||
if (-not $hasGcc) {
|
||||
Write-Warn2 "未检测到 gcc,silkdecode 依赖 cgo 无法编译,跳过。语音消息自动转码功能在此构建中不可用。"
|
||||
Write-Warn2 "如需启用:安装 MinGW-w64(如 winget install -e --id mstorsjo.llvm-mingw 或 choco install mingw),再重新打包。"
|
||||
} else {
|
||||
New-Item -ItemType Directory -Force -Path (Split-Path $silkOut) | Out-Null
|
||||
Push-Location (Join-Path $repoRoot "tools\audio\silkdecode")
|
||||
try {
|
||||
$oldCgo = $env:CGO_ENABLED
|
||||
$env:CGO_ENABLED = "1"
|
||||
& $go build -trimpath -ldflags "-s -w" -o $silkOut .
|
||||
if ($LASTEXITCODE -eq 0 -and (Test-Path $silkOut)) { $silkBuilt = $true; Write-Ok "silkdecode.exe 完成" }
|
||||
else { Write-Warn2 "silkdecode 编译失败,已跳过(不影响主程序)。" }
|
||||
} finally {
|
||||
Pop-Location
|
||||
if ($null -eq $oldCgo) { Remove-Item Env:CGO_ENABLED -ErrorAction SilentlyContinue } else { $env:CGO_ENABLED = $oldCgo }
|
||||
}
|
||||
}
|
||||
|
||||
# ---- 主程序 + 前端 ----
|
||||
Write-Step "构建主程序 (wails build)"
|
||||
& $wails build -trimpath -webview2 embed
|
||||
if ($LASTEXITCODE -ne 0) { throw "wails build 失败 (exit $LASTEXITCODE)" }
|
||||
$mainExe = Join-Path $binDir "qiweimanager.exe"
|
||||
if (-not (Test-Path $mainExe)) { throw "主程序未生成: $mainExe" }
|
||||
Write-Ok "qiweimanager.exe 完成"
|
||||
|
||||
# ---- 汇总绿色免安装版 ----
|
||||
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
||||
$distDirWithTime = Join-Path $repoRoot "dist\qiweimanager_$timestamp"
|
||||
Write-Step "汇总绿色免安装版到 dist\qiweimanager_$timestamp"
|
||||
if (Test-Path $distDirWithTime) { Remove-Item $distDirWithTime -Recurse -Force }
|
||||
New-Item -ItemType Directory -Force -Path $distDirWithTime | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path (Join-Path $distDirWithTime "config\knowledge") | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path (Join-Path $distDirWithTime "config\materials") | Out-Null
|
||||
|
||||
$mainExeWithTime = "qiweimanager_$timestamp.exe"
|
||||
Copy-Required -Source $mainExe -Destination (Join-Path $distDirWithTime $mainExeWithTime)
|
||||
Copy-Required -Source $helperOut -Destination (Join-Path $distDirWithTime "helper.exe")
|
||||
if ($silkBuilt) {
|
||||
Copy-Required -Source $silkOut -Destination (Join-Path $distDirWithTime "tools\audio\silkdecode.exe")
|
||||
} else {
|
||||
Write-Warn2 "dist 不含 silkdecode.exe(语音转码功能不可用)。"
|
||||
}
|
||||
Copy-Required -Source (Join-Path $repoRoot "Helper_4.1.33.6009.dll") -Destination (Join-Path $distDirWithTime "Helper_4.1.33.6009.dll")
|
||||
Copy-Required -Source (Join-Path $repoRoot "Loader_4.1.33.6009.dll") -Destination (Join-Path $distDirWithTime "Loader_4.1.33.6009.dll")
|
||||
Copy-Item -LiteralPath (Join-Path $repoRoot "requestdata") -Destination (Join-Path $distDirWithTime "requestdata") -Recurse -Force
|
||||
Copy-Item -LiteralPath (Join-Path $repoRoot "eventdata") -Destination (Join-Path $distDirWithTime "eventdata") -Recurse -Force
|
||||
|
||||
# 默认配置(不含真实密钥)
|
||||
$defaultConfig = @'
|
||||
{
|
||||
"callbackConfig": {
|
||||
"callbackUrl": "",
|
||||
"callbackToken": "",
|
||||
"httpPort": "10001",
|
||||
"enableCallback": false,
|
||||
"enableCloudAuth": false,
|
||||
"fileUploadUrl": "",
|
||||
"deviceCode": ""
|
||||
},
|
||||
"lastUpdated": 0
|
||||
}
|
||||
'@
|
||||
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
|
||||
[System.IO.File]::WriteAllText((Join-Path $distDirWithTime "config\config.json"), $defaultConfig, $utf8NoBom)
|
||||
[System.IO.File]::WriteAllText((Join-Path $distDirWithTime "config\client_status.json"), "{}", $utf8NoBom)
|
||||
[System.IO.File]::WriteAllText((Join-Path $distDirWithTime "config\materials\materials.json"), '{"materials":[]}', $utf8NoBom)
|
||||
|
||||
Write-Host ""
|
||||
Write-Step "打包完成"
|
||||
Write-Ok "绿色免安装版: $distDirWithTime"
|
||||
Write-Ok "主程序: $mainExeWithTime"
|
||||
Write-Ok "直接进入该目录双击 $mainExeWithTime 即可运行。"
|
||||
Write-Host " 如需 NSIS 安装包,请安装 NSIS 后运行: scripts\build.ps1 -Installer" -ForegroundColor DarkGray
|
||||
213
scripts/dev.ps1
Normal file
213
scripts/dev.ps1
Normal file
@@ -0,0 +1,213 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
一键本地开发启动脚本。
|
||||
|
||||
.DESCRIPTION
|
||||
自动完成以下工作,然后运行 `wails dev`:
|
||||
1. 定位 Go 与 Wails CLI(即使未写入 PATH 也能找到常见安装位置)。
|
||||
2. 把 Go / Wails 注入当前会话 PATH,并设置 GOCACHE 到仓库内的 .gocache。
|
||||
3. 首次运行时自动安装前端依赖(frontend/node_modules)与 Go 模块。
|
||||
4. 校验企业微信调试所需的 helper.exe 与 DLL 是否在运行目录。
|
||||
5. 启动 wails dev(前端热更新 + Go 热重载)。
|
||||
|
||||
.PARAMETER SkipInstall
|
||||
跳过依赖安装检查,直接启动(依赖已装好时更快)。
|
||||
|
||||
.PARAMETER GoPath
|
||||
手动指定 go.exe 路径(自动探测失败时使用)。
|
||||
|
||||
.PARAMETER WailsPath
|
||||
手动指定 wails.exe 路径(自动探测失败时使用)。
|
||||
|
||||
.EXAMPLE
|
||||
powershell -ExecutionPolicy Bypass -File scripts\dev.ps1
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[switch]$SkipInstall,
|
||||
[string]$GoPath,
|
||||
[string]$WailsPath
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$repoRoot = (Resolve-Path (Join-Path $scriptDir "..")).Path
|
||||
Set-Location $repoRoot
|
||||
|
||||
function Write-Step([string]$msg) { Write-Host "==> $msg" -ForegroundColor Cyan }
|
||||
function Write-Ok([string]$msg) { Write-Host " $msg" -ForegroundColor Green }
|
||||
function Write-Warn2([string]$msg){ Write-Host " $msg" -ForegroundColor Yellow }
|
||||
|
||||
# ---- 定位 Go ----
|
||||
function Resolve-Go {
|
||||
param([string]$Hint)
|
||||
$candidates = @()
|
||||
if ($Hint) { $candidates += $Hint }
|
||||
$cmd = Get-Command go.exe -ErrorAction SilentlyContinue
|
||||
if ($cmd) { $candidates += $cmd.Source }
|
||||
$candidates += "$env:LOCALAPPDATA\Programs\Go\bin\go.exe"
|
||||
$candidates += "C:\Program Files\Go\bin\go.exe"
|
||||
$candidates += "C:\Go\bin\go.exe"
|
||||
foreach ($c in $candidates) { if ($c -and (Test-Path $c)) { return (Resolve-Path $c).Path } }
|
||||
throw "未找到 Go。请安装 Go 1.24+ 后重试,或用 -GoPath 指定 go.exe。"
|
||||
}
|
||||
|
||||
# ---- 定位 Wails CLI ----
|
||||
function Resolve-Wails {
|
||||
param([string]$Hint)
|
||||
$candidates = @()
|
||||
if ($Hint) { $candidates += $Hint }
|
||||
$cmd = Get-Command wails.exe -ErrorAction SilentlyContinue
|
||||
if ($cmd) { $candidates += $cmd.Source }
|
||||
$candidates += "$env:USERPROFILE\go\bin\wails.exe"
|
||||
foreach ($c in $candidates) { if ($c -and (Test-Path $c)) { return (Resolve-Path $c).Path } }
|
||||
return $null
|
||||
}
|
||||
|
||||
# ---- 环境准备 ----
|
||||
Write-Step "定位 Go / Wails 工具链"
|
||||
$go = Resolve-Go -Hint $GoPath
|
||||
$goBin = Split-Path -Parent $go
|
||||
$goPathBin = Join-Path $env:USERPROFILE "go\bin"
|
||||
$env:PATH = "$goBin;$goPathBin;$env:PATH"
|
||||
Write-Ok "Go: $go"
|
||||
|
||||
$wails = Resolve-Wails -Hint $WailsPath
|
||||
if (-not $wails) {
|
||||
Write-Warn2 "未找到 Wails CLI,正在安装(go install)..."
|
||||
& $go install github.com/wailsapp/wails/v2/cmd/wails@latest
|
||||
$wails = Resolve-Wails
|
||||
if (-not $wails) { throw "Wails CLI 安装失败,请检查网络或 GOPROXY。" }
|
||||
}
|
||||
Write-Ok "Wails: $wails"
|
||||
|
||||
# GOCACHE 放仓库内,避免污染系统缓存
|
||||
$goCache = Join-Path $repoRoot ".gocache"
|
||||
New-Item -ItemType Directory -Force -Path $goCache | Out-Null
|
||||
$env:GOCACHE = $goCache
|
||||
|
||||
# ---- 依赖安装 ----
|
||||
if (-not $SkipInstall) {
|
||||
$nodeModules = Join-Path $repoRoot "frontend\node_modules"
|
||||
if (-not (Test-Path $nodeModules)) {
|
||||
Write-Step "安装前端依赖 (npm install)"
|
||||
Push-Location (Join-Path $repoRoot "frontend")
|
||||
try { & npm install } finally { Pop-Location }
|
||||
Write-Ok "前端依赖安装完成"
|
||||
} else {
|
||||
Write-Ok "前端依赖已存在,跳过 npm install"
|
||||
}
|
||||
|
||||
Write-Step "同步 Go 模块 (go mod download)"
|
||||
& $go mod download
|
||||
Write-Ok "Go 模块就绪"
|
||||
}
|
||||
|
||||
# ---- 编译 32 位 helper.exe(统一用正确链接参数,杜绝手动编错导致主程序拉起即崩)----
|
||||
# helper 必须 GOARCH=386 且带 -H windowsgui:主程序是 GUI 子系统,用 CreateProcess 拉起 helper 时
|
||||
# 不分配控制台;若 helper 误编成默认 console 子系统(漏掉 -H windowsgui),被主程序拉起后会因标准
|
||||
# 句柄处理立即崩溃——表现为主程序日志「辅助程序已成功启动 PID=xxxx」但该 PID 秒退、不写日志、
|
||||
# 10001 端口无人监听、前端“启动企微”无反应、满屏 dial tcp [::1]:10001 拒绝连接。诡异之处在于
|
||||
# console 版 helper 在终端手动运行一切正常,只有被主程序拉起才崩,极易误判为二进制本身没问题。
|
||||
# 这里每次 dev 启动都用与 scripts\build.ps1 完全一致的参数重编 helper,既保证 helper 源码改动生效,
|
||||
# 又把“唯一正确的编译方式”固化进脚本,从源头消除编错风险。
|
||||
Write-Step "编译 32 位 helper.exe"
|
||||
$binDir = Join-Path $repoRoot "build\bin"
|
||||
New-Item -ItemType Directory -Force -Path $binDir | Out-Null
|
||||
$helperOut = Join-Path $binDir "helper.exe"
|
||||
|
||||
# 先停掉可能占用 helper.exe 的残留进程,否则无法覆盖输出文件。
|
||||
Get-Process -Name "helper", "helper_auto_reply" -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
Write-Warn2 "结束残留 helper 进程 (PID $($_.Id))"
|
||||
Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
$oldArch = $env:GOARCH
|
||||
$oldCgo = $env:CGO_ENABLED
|
||||
try {
|
||||
$env:GOARCH = "386"
|
||||
$env:CGO_ENABLED = "0"
|
||||
Push-Location (Join-Path $repoRoot "helper")
|
||||
& $go build -trimpath -ldflags "-H windowsgui -s -w" -o $helperOut .
|
||||
$helperExit = $LASTEXITCODE
|
||||
} finally {
|
||||
Pop-Location
|
||||
if ($null -eq $oldArch) { Remove-Item Env:GOARCH -ErrorAction SilentlyContinue } else { $env:GOARCH = $oldArch }
|
||||
if ($null -eq $oldCgo) { Remove-Item Env:CGO_ENABLED -ErrorAction SilentlyContinue } else { $env:CGO_ENABLED = $oldCgo }
|
||||
}
|
||||
if ($helperExit -ne 0) { throw "helper.exe 编译失败 (exit $helperExit)。企业微信链路将不可用,请检查 helper 目录源码。" }
|
||||
|
||||
# 子系统自检:windowsgui 版的 PE 头 Subsystem 字段为 2(GUI),console 版为 3。若意外编出 console 版直接拦下。
|
||||
try {
|
||||
$bytes = [System.IO.File]::ReadAllBytes($helperOut)
|
||||
$peOff = [System.BitConverter]::ToInt32($bytes, 0x3C) # e_lfanew → PE 头偏移
|
||||
$subsystem = [System.BitConverter]::ToUInt16($bytes, $peOff + 0x5C) # OptionalHeader.Subsystem
|
||||
if ($subsystem -eq 2) {
|
||||
Write-Ok "helper.exe 已编译 (GOARCH=386, GUI 子系统,可被主程序安全拉起)"
|
||||
} else {
|
||||
throw "helper.exe 子系统为 $subsystem(期望 2=GUI)。这会导致主程序拉起即崩,请确认编译参数含 -H windowsgui。"
|
||||
}
|
||||
} catch [System.Management.Automation.RuntimeException] {
|
||||
throw
|
||||
} catch {
|
||||
Write-Warn2 "helper.exe 子系统自检跳过:$($_.Exception.Message)"
|
||||
}
|
||||
|
||||
$wxDlls = @("Helper_4.1.33.6009.dll", "Loader_4.1.33.6009.dll")
|
||||
foreach ($dll in $wxDlls) {
|
||||
if (Test-Path (Join-Path $repoRoot $dll)) { Write-Ok "$dll 已就绪" } else { Write-Warn2 "缺少 $dll,企业微信链路可能无法工作" }
|
||||
}
|
||||
|
||||
# wails dev 把主程序与 helper 跑在 build\bin 下,helper 需要在自身目录找到这两个 DLL。
|
||||
# 仓库根目录有 DLL 但 build\bin 没有 → "启动企微"会失败并提示 No Helper_*.dll found。
|
||||
# 这里把根目录 DLL 同步到 build\bin(build\bin 由 wails 在编译时创建,缺失则跳过,启动后会自动建好;
|
||||
# 若本次启动后仍报缺 DLL,再次运行本脚本即可补齐)。
|
||||
$binDir = Join-Path $repoRoot "build\bin"
|
||||
if (Test-Path $binDir) {
|
||||
foreach ($dll in $wxDlls) {
|
||||
$src = Join-Path $repoRoot $dll
|
||||
if (-not (Test-Path $src)) { continue }
|
||||
$dst = Join-Path $binDir $dll
|
||||
# 目标已是同样大小则无需复制(避免覆盖正被 helper 占用的 DLL 而报错)
|
||||
if ((Test-Path $dst) -and ((Get-Item $dst).Length -eq (Get-Item $src).Length)) {
|
||||
Write-Ok "$dll 已在 build\bin(无需同步)"
|
||||
continue
|
||||
}
|
||||
try {
|
||||
Copy-Item -LiteralPath $src -Destination $dst -Force
|
||||
Write-Ok "已同步 $dll 到 build\bin"
|
||||
} catch {
|
||||
if (Test-Path $dst) {
|
||||
Write-Warn2 "$dll 正被占用无法更新,但 build\bin 已有可用副本,继续。"
|
||||
} else {
|
||||
Write-Warn2 "同步 $dll 到 build\bin 失败且目标缺失:$($_.Exception.Message)。请先结束残留 helper.exe 再重试。"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Warn2 "build\bin 尚不存在(首次编译后才会创建)。若启动后“启动企微”提示缺少 DLL,请重新运行本脚本以同步。"
|
||||
}
|
||||
|
||||
# helper 运行时要在自身目录(build\bin)下按消息类型号读取 eventdata\<type>.json 模板来翻译企微事件。
|
||||
# 若 build\bin 缺少 eventdata,TransformData 会走兜底分支并丢掉顶层 type 字段,导致文本消息被误判成图片、
|
||||
# 触发图片识别失败并反复回复“无法识别这条图片/视频内容”。requestdata 同理为运行时资源。
|
||||
# 这里每次 dev 启动都把仓库根目录的 eventdata/requestdata 同步到 build\bin,从源头杜绝该问题复发。
|
||||
if (Test-Path $binDir) {
|
||||
foreach ($resource in @("eventdata", "requestdata")) {
|
||||
$src = Join-Path $repoRoot $resource
|
||||
if (-not (Test-Path $src)) { Write-Warn2 "仓库缺少 $resource 目录,跳过同步"; continue }
|
||||
$dst = Join-Path $binDir $resource
|
||||
try {
|
||||
Copy-Item -LiteralPath $src -Destination $binDir -Recurse -Force
|
||||
Write-Ok "已同步 $resource 到 build\bin"
|
||||
} catch {
|
||||
Write-Warn2 "同步 $resource 到 build\bin 失败:$($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ---- 启动 ----
|
||||
Write-Step "启动 wails dev(Ctrl+C 退出)"
|
||||
Write-Host ""
|
||||
& $wails dev
|
||||
@@ -112,7 +112,20 @@ $env:GOCACHE = (Resolve-Path (Join-Path $repoRoot ".gocache")).Path
|
||||
|
||||
$wailsFallback = if ($WailsPath) { $WailsPath } else { Join-Path $env:USERPROFILE "go\bin\wails.exe" }
|
||||
$wails = Resolve-RequiredTool -Name "wails.exe" -FallbackPath $wailsFallback -InstallHint "Install Wails CLI on the build machine first."
|
||||
$makensis = Resolve-RequiredTool -Name "makensis.exe" -FallbackPath $MakensisPath -InstallHint "Install NSIS on the build machine first, e.g. run as Administrator: choco install nsis -y; or pass -MakensisPath."
|
||||
|
||||
# 自动探测 NSIS 标准安装路径(未在 PATH 时也能找到),优先使用显式传入的 -MakensisPath
|
||||
$makensisFallback = $null
|
||||
$makensisCandidates = @()
|
||||
if ($MakensisPath) { $makensisCandidates += $MakensisPath }
|
||||
$makensisCandidates += @(
|
||||
(Join-Path ${env:ProgramFiles(x86)} "NSIS\makensis.exe"),
|
||||
(Join-Path $env:ProgramFiles "NSIS\makensis.exe"),
|
||||
(Join-Path $env:LOCALAPPDATA "Programs\NSIS\makensis.exe")
|
||||
)
|
||||
foreach ($candidate in $makensisCandidates) {
|
||||
if ($candidate -and (Test-Path -LiteralPath $candidate)) { $makensisFallback = $candidate; break }
|
||||
}
|
||||
$makensis = Resolve-RequiredTool -Name "makensis.exe" -FallbackPath $makensisFallback -InstallHint "Install NSIS on the build machine first, e.g. run as Administrator: choco install nsis -y; or pass -MakensisPath."
|
||||
$npm = Resolve-RequiredTool -Name "npm.cmd" -InstallHint "Install Node.js on the build machine first."
|
||||
$go = Resolve-RequiredTool -Name "go.exe" -InstallHint "Install Go on the build machine first."
|
||||
$pdftoppm = Get-Command "pdftoppm.exe" -ErrorAction SilentlyContinue
|
||||
@@ -149,12 +162,20 @@ try {
|
||||
|
||||
Write-Host "==> Building bundled silk decoder"
|
||||
$silkDecoderOut = Join-Path $binDir "tools\audio\silkdecode.exe"
|
||||
New-Item -ItemType Directory -Force -Path (Split-Path $silkDecoderOut) | Out-Null
|
||||
Push-Location (Join-Path $repoRoot "tools\audio\silkdecode")
|
||||
try {
|
||||
& $go build -trimpath -ldflags "-s -w" -o $silkDecoderOut .
|
||||
} finally {
|
||||
Pop-Location
|
||||
$silkBuilt = $false
|
||||
if (-not (Get-Command gcc -ErrorAction SilentlyContinue)) {
|
||||
Write-Warning "gcc not found; silkdecode requires cgo and will be skipped. Voice message transcoding will be unavailable."
|
||||
} else {
|
||||
New-Item -ItemType Directory -Force -Path (Split-Path $silkDecoderOut) | Out-Null
|
||||
Push-Location (Join-Path $repoRoot "tools\audio\silkdecode")
|
||||
try {
|
||||
$oldCgo = $env:CGO_ENABLED; $env:CGO_ENABLED = "1"
|
||||
& $go build -trimpath -ldflags "-s -w" -o $silkDecoderOut .
|
||||
if ($LASTEXITCODE -eq 0) { $silkBuilt = $true } else { Write-Warning "silkdecode build failed, skipping." }
|
||||
} finally {
|
||||
Pop-Location
|
||||
if ($null -eq $oldCgo) { Remove-Item Env:CGO_ENABLED -ErrorAction SilentlyContinue } else { $env:CGO_ENABLED = $oldCgo }
|
||||
}
|
||||
}
|
||||
|
||||
if ($pdftoppm) {
|
||||
@@ -185,7 +206,11 @@ if (-not $SkipFrontendBuild) {
|
||||
Write-Host "==> Building frontend"
|
||||
Push-Location (Join-Path $repoRoot "frontend")
|
||||
try {
|
||||
& $npm run build
|
||||
# 原生命令往 stderr 写警告会在 Stop 策略下被误判为失败,这里改按退出码判断
|
||||
$oldEap = $ErrorActionPreference; $ErrorActionPreference = "Continue"
|
||||
& $npm run build 2>&1 | ForEach-Object { "$_" }
|
||||
$ErrorActionPreference = $oldEap
|
||||
if ($LASTEXITCODE -ne 0) { throw "frontend build failed (exit $LASTEXITCODE)" }
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
@@ -197,7 +222,11 @@ New-Item -ItemType Directory -Force -Path (Join-Path $runtimeDir "config\knowled
|
||||
New-Item -ItemType Directory -Force -Path (Join-Path $runtimeDir "config\materials") | Out-Null
|
||||
|
||||
Copy-RequiredFile -Source $helperOut -Destination (Join-Path $runtimeDir "helper.exe")
|
||||
Copy-RequiredFile -Source $silkDecoderOut -Destination (Join-Path $runtimeDir "tools\audio\silkdecode.exe")
|
||||
if ($silkBuilt -and (Test-Path -LiteralPath $silkDecoderOut)) {
|
||||
Copy-RequiredFile -Source $silkDecoderOut -Destination (Join-Path $runtimeDir "tools\audio\silkdecode.exe")
|
||||
} else {
|
||||
Write-Warning "silkdecode.exe not bundled (gcc unavailable); voice transcoding disabled in this installer."
|
||||
}
|
||||
if (Test-Path -LiteralPath (Join-Path $binDir "tools\pdf\pdftoppm.exe")) {
|
||||
Copy-RequiredFile -Source (Join-Path $binDir "tools\pdf\pdftoppm.exe") -Destination (Join-Path $runtimeDir "tools\pdf\pdftoppm.exe")
|
||||
}
|
||||
@@ -239,11 +268,17 @@ if (Test-Path -LiteralPath $materialsIndex) {
|
||||
}
|
||||
|
||||
Write-Host "==> Building Wails NSIS installer"
|
||||
& $wails build --nsis -webview2 embed -trimpath
|
||||
$oldEap = $ErrorActionPreference; $ErrorActionPreference = "Continue"
|
||||
& $wails build --nsis -webview2 embed -trimpath 2>&1 | ForEach-Object { "$_" }
|
||||
$ErrorActionPreference = $oldEap
|
||||
|
||||
$installer = Join-Path $binDir "qiweimanager-amd64-installer.exe"
|
||||
if (-not (Test-Path -LiteralPath $installer)) {
|
||||
throw "Installer was not generated: $installer"
|
||||
}
|
||||
|
||||
Write-Host "==> Release complete: $installer"
|
||||
# 添加时间戳到安装包文件名
|
||||
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
||||
$installerWithTime = Join-Path $binDir "qiweimanager-amd64-installer_$timestamp.exe"
|
||||
Move-Item -LiteralPath $installer -Destination $installerWithTime -Force
|
||||
Write-Host "==> Release complete: $installerWithTime"
|
||||
|
||||
Reference in New Issue
Block a user