- 添加dist/目录到.gitignore,用于排除打包输出的绿色免安装版 - 添加Wails打包过程中的临时文件和自动生成文件到.gitignore - 删除build/windows/installer/wails_tools.nsh自动生成文件 - 添加Windows安装器临时目录和Webview2安装文件到忽略列表 feat(docs): 添加万川平台对接文档和产品素材 - 创建万川平台登录到获取模型信息的流程说明文档 - 添加万川平台对接实施计划文档 - 新增产品图片、公司简介图、宣传海报、教程截图、案例展示等素材文件 refactor(runtime): 扩展通知功能类型定义 - 添加NotificationOptions接口定义 - 添加NotificationAction接口定义 - 添加NotificationCategory接口定义 - 扩展通知相关的运行时API类型声明,包括初始化、发送、注册分类等功能
214 lines
9.5 KiB
PowerShell
214 lines
9.5 KiB
PowerShell
<#
|
||
.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
|