1adf088c68
ci-pangolin / OpenAPI Sync Check (push) Successful in 20s
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Successful in 6s
ci-pangolin / Flutter — analyze + test (push) Successful in 24s
ci-pangolin / Portable SQL — 可移植性 (mysql/sqlite) (push) Successful in 6s
ci-pangolin / Codegen Drift — token 生成物未漂移 (push) Successful in 5s
ci-pangolin / Go — build + test (push) Successful in 9s
ci-pangolin / E2E Smoke — L4 进程级端到端 (push) Successful in 16s
ci-pangolin / Go — integration (mysql/redis testcontainers) (push) Successful in 4m13s
ci-pangolin / Golden — 视觉回归 (components + auth) (push) Successful in 15s
ci-pangolin / Lint — shellcheck (push) Failing after 11m42s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
89 lines
3.4 KiB
Plaintext
89 lines
3.4 KiB
Plaintext
; 穿山甲 Pangolin Windows 安装包 (Inno Setup 6)
|
|
; 编译: ISCC.exe pangolin.iss (或用 Inno Setup Compiler 打开)
|
|
; 前置: 先在 client/ 跑 `flutter build windows`(Release),产物在
|
|
; ..\..\build\windows\x64\runner\Release
|
|
#define MyAppName "穿山甲 Pangolin"
|
|
#define MyAppVersion "1.0.9"
|
|
#define MyAppPublisher "Pangolin"
|
|
#define MyAppExeName "pangolin_vpn.exe"
|
|
#define BuildDir "..\..\build\windows\x64\runner\Release"
|
|
|
|
[Setup]
|
|
AppId={{B2F1B0A0-7A3C-4C2E-9E5A-1A2B3C4D5E6F}
|
|
AppName={#MyAppName}
|
|
AppVersion={#MyAppVersion}
|
|
AppPublisher={#MyAppPublisher}
|
|
DefaultDirName={autopf}\Pangolin
|
|
DefaultGroupName=Pangolin
|
|
DisableProgramGroupPage=yes
|
|
OutputBaseFilename=pangolin-setup-{#MyAppVersion}
|
|
Compression=lzma2
|
|
SolidCompression=yes
|
|
WizardStyle=modern
|
|
; 安装需管理员(写 Program Files;app 本身 requireAdministrator)
|
|
PrivilegesRequired=admin
|
|
ArchitecturesInstallIn64BitMode=x64compatible
|
|
|
|
[Languages]
|
|
; ChineseSimplified.isl 随仓库附带(此 Inno Setup 安装未含官方简中语言包),与本 .iss 同目录
|
|
Name: "chinesesimplified"; MessagesFile: "ChineseSimplified.isl"
|
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
|
|
|
[Files]
|
|
; 整个 Release 目录(含 pangolin_vpn.exe / flutter_windows.dll / data\ /
|
|
; 插件 dll / sing-box.exe / wintun.dll)
|
|
Source: "{#BuildDir}\*"; DestDir: "{app}"; Flags: recursesubdirs createallsubdirs ignoreversion
|
|
|
|
[Icons]
|
|
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
|
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
|
|
|
|
[Tasks]
|
|
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"
|
|
|
|
[Run]
|
|
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#MyAppName}}"; Flags: nowait postinstall skipifsilent
|
|
|
|
[UninstallDelete]
|
|
; 卸载清理运行期数据(kernel 配置等)
|
|
Type: filesandordirs; Name: "{localappdata}\Pangolin"
|
|
|
|
[Code]
|
|
{ ── 升级覆盖修复 ──────────────────────────────────────────────────────────
|
|
历史坑:1.0.0 的 AppId 是非法 GUID(...PANGOLIN0001),1.0.1 起改成当前合法
|
|
GUID。AppId 不同 → Inno 视为两个独立产品 → 旧版不被覆盖,控制面板里并排两个。
|
|
当前 AppId 已稳定(1.0.1+ 同源,会原地升级);此处在安装前再把那个遗留 AppId
|
|
的残留装静默卸掉,清掉已并存的 1.0.0 幽灵,杜绝多版本并排。}
|
|
const
|
|
LegacyAppId = '{B2F1B0A0-7A3C-4C2E-9E5A-PANGOLIN0001}_is1';
|
|
|
|
function GetUninstallString(const SubKey: string): string;
|
|
var
|
|
s: string;
|
|
begin
|
|
s := '';
|
|
if not RegQueryStringValue(HKLM64, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + SubKey, 'UninstallString', s) then
|
|
if not RegQueryStringValue(HKLM32, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + SubKey, 'UninstallString', s) then
|
|
RegQueryStringValue(HKCU, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + SubKey, 'UninstallString', s);
|
|
Result := s;
|
|
end;
|
|
|
|
procedure RemoveLegacyVersion;
|
|
var
|
|
uninst: string;
|
|
rc: Integer;
|
|
begin
|
|
uninst := GetUninstallString(LegacyAppId);
|
|
if uninst <> '' then
|
|
begin
|
|
uninst := RemoveQuotes(uninst);
|
|
Exec(uninst, '/VERYSILENT /SUPPRESSMSGBOXES /NORESTART', '', SW_HIDE, ewWaitUntilTerminated, rc);
|
|
end;
|
|
end;
|
|
|
|
procedure CurStepChanged(CurStep: TSetupStep);
|
|
begin
|
|
if CurStep = ssInstall then
|
|
RemoveLegacyVersion;
|
|
end;
|