From bb51949974c14989f20105d688146cac14f86352 Mon Sep 17 00:00:00 2001 From: yuejiajun <1530620364@qq.com> Date: Fri, 15 Aug 2025 15:37:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=98=E6=9B=B4=E5=AE=89=E8=A3=85=E6=96=B9?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- base/install_base.iss | 210 ++++++++++++++++++++++++++++-------------- 1 file changed, 141 insertions(+), 69 deletions(-) diff --git a/base/install_base.iss b/base/install_base.iss index c09c663..e1ebb4c 100644 --- a/base/install_base.iss +++ b/base/install_base.iss @@ -38,7 +38,7 @@ AppSupportURL={#MyAppURL} AppUpdatesURL={#MyAppURL} ChangesAssociations=yes DisableDirPage=no -DisableProgramGroupPage=no +DisableProgramGroupPage=yes Compression=lzma2 SolidCompression=yes WizardStyle=modern @@ -52,45 +52,56 @@ OutputBaseFilename=Setup-{#MyAppVersion} ; 语言选择 [Languages] -Name: "Chinese"; MessagesFile: "compiler:Languages\Chinese.isl" +Name: "Chinese"; MessagesFile: "compiler:Languages\Chinese.isl"; + + +;; 任务 +[Tasks] +; 是否创建桌面图标 +;Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked ;; 组件安装方式 [Types] -Name: "full"; Description: "完整组件安装" -Name: "custom"; Description: "自定义组件安装" +Name: "full"; Description: "完整组件安装"; +Name: "mini"; Description: "最小安装"; +; iscustom 开启自定义选项 +Name: "custom"; Description: "自定义组件安装"; Flags: iscustom; ;; 组件列表选择项 [Components] -Name: "MainApp"; Description: "{#MyAppName}主程序"; Types: full; Flags: checkablealone fixed -Name: "JDK"; Description: "JDK程序"; Types: full custom -Name: "Redis"; Description: "Redis程序"; Types: full custom -Name: "MinIO"; Description: "MinIO程序"; Types: full custom -Name: "RocketMQ"; Description: "RocketMQ程序"; Types: full custom -Name: "Nginx"; Description: "Nginx程序"; Types: full custom -Name: "MySQL"; Description: "MySQL程序"; Types: full custom +Name: "MainApp"; Description: "{#MyAppName}主程序"; Types: full mini; Flags: checkablealone; +Name: "JDK"; Description: "JDK程序"; Types: full custom; Flags: checkablealone; +Name: "Redis"; Description: "Redis程序"; Types: full custom; Flags: checkablealone; +Name: "MinIO"; Description: "MinIO程序"; Types: full custom; Flags: checkablealone; +Name: "RocketMQ"; Description: "RocketMQ程序"; Types: full custom; Flags: checkablealone; +Name: "Nginx"; Description: "Nginx程序"; Types: full custom; Flags: checkablealone; +Name: "MySQL"; Description: "MySQL程序"; Types: full custom; Flags: checkablealone; ;; 引入文件列表 [Files] ;; Readme -Source: "Resources\Readme.md"; DestDir: "{app}"; Flags: isreadme +; 安装完的 readme 信息 +Source: "Resources\Readme.md"; DestDir: "{app}"; Flags: isreadme; ;; 文件 -Source: "Resources\grep.exe"; DestDir: "{app}\usr"; DestName: "grep.exe"; Flags: ignoreversion; Components: MainApp +Source: "Resources\grep.exe"; DestDir: "{app}\usr"; DestName: "grep.exe"; Flags: ignoreversion; Components: MainApp; ;; 文件夹 -Source: "Resources\usr\*"; DestDir: "{app}\usr\"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: MainApp -Source: "Resources\jdk\*"; DestDir: "{app}\jdk\"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: JDK -Source: "Resources\redis\*"; DestDir: "{app}\redis\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: Redis -Source: "Resources\io\*"; DestDir: "{app}\io\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: MinIO -Source: "Resources\rocketmq\*"; DestDir: "{app}\rocketmq\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: RocketMQ -Source: "Resources\nginx\*"; DestDir: "{app}\nginx\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: Nginx -Source: "Resources\mysql\*"; DestDir: "{app}\mysql\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: MySQL +; recursesubdirs createallsubdirs 递归复制整个目录 +Source: "Resources\usr\*"; DestDir: "{app}\usr\"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: MainApp; +; onlyifdoesntexist 当文件不存在时安装 +Source: "Resources\jdk\*"; DestDir: "{app}\jdk\"; Flags: ignoreversion recursesubdirs createallsubdirs onlyifdoesntexist; Components: JDK; +Source: "Resources\redis\*"; DestDir: "{app}\redis\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: Redis; +Source: "Resources\io\*"; DestDir: "{app}\io\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: MinIO; +Source: "Resources\rocketmq\*"; DestDir: "{app}\rocketmq\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: RocketMQ; +Source: "Resources\nginx\*"; DestDir: "{app}\nginx\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: Nginx; +Source: "Resources\mysql\*"; DestDir: "{app}\mysql\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: MySQL; ;; 创建必要目录 [Dirs] -Name: "{app}\nginx\dist"; Permissions: users-modify +Name: "{app}\nginx\dist"; Permissions: users-modify; Components: Nginx; ;; 安装前后删除文件 @@ -102,78 +113,82 @@ Type: files; Name: "{app}\mysql\template.ini"; ;; 安装时注册表与环境变量列表 [Registry] -; 写入普通注册表项 -Root: HKLM; Subkey: "Software\X\Command"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}"; Flags: uninsdeletekey -Root: HKLM; Subkey: "Software\X\Command"; ValueType: string; ValueName: "Version"; ValueData: "{#SetupSetting("AppVersion")}" +;; 写入普通注册表项 +; uninsdeletevalue 卸载时删除值 +; uninsdeletekey 卸载时删除键 +; preservestringtype 保留原值类型 +Root: HKLM; Subkey: "Software\X\Command"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}"; Flags: uninsdeletevalue ; +Root: HKLM; Subkey: "Software\X\Command"; ValueType: string; ValueName: "Version"; ValueData: "{#SetupSetting("AppVersion")}"; Flags: uninsdeletevalue ; -; 默认注册信息 -Root: HKA; Subkey: "Software\Classes\{#MyAppAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#MyAppAssocKey}"; ValueData: ""; Flags: uninsdeletevalue -Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#MyAppAssocName}"; Flags: uninsdeletekey -Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName}.exe,0" -Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}.exe"" ""%1""" +;; 默认注册信息 +Root: HKA; Subkey: "Software\Classes\{#MyAppAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#MyAppAssocKey}"; ValueData: ""; Flags: uninsdeletevalue; +Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#MyAppAssocName}"; Flags: uninsdeletevalue; +Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName}.exe,0"; Flags: uninsdeletevalue; +Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}.exe"" ""%1"""; Flags: uninsdeletevalue; -;; 【grep、awk、sed、rar、zip、tar...】(通用服务) -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: MainApp; \ - ValueName: "X_COMMAND"; ValueData: "{app}"; -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: MainApp; \ - ValueName: "Path"; ValueData: "{olddata};%X_COMMAND%\usr"; Check: NeedsAddPath('%X_COMMAND%\usr'); +;; 【grep、awk、sed、head、sort、ls、rm、xargs、rar、zip、tar、md5sum、sha1sum...】 +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; AfterInstall: RefreshEnvironment; Components: MainApp; \ + ValueName: "X_COMMAND"; ValueData: "{app}"; Flags: uninsdeletevalue ; +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; AfterInstall: RefreshEnvironment; Components: MainApp; \ + ValueName: "Path"; ValueData: "{olddata};%X_COMMAND%\usr"; Check: NeedsAddPath('%X_COMMAND%\usr'); Flags: uninsdeletevalue ; -; 【Java】追加到 PATH 变量 -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: JDK; \ - ValueName: "Path"; ValueData: "{olddata};%JAVA_HOME%\bin"; Check: NeedsAddPath('%JAVA_HOME%\bin'); -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: JDK; \ - ValueName: "JAVA_HOME"; ValueData: "{app}\jdk"; -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: JDK; \ - ValueName: "JDK_21"; ValueData: "{app}\jdk"; +;; 【Java】追加到 PATH 变量 +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; AfterInstall: RefreshEnvironment; Components: JDK; \ + ValueName: "Path"; ValueData: "{olddata};%JAVA_HOME%\bin"; Check: NeedsAddPath('%JAVA_HOME%\bin'); Flags: preservestringtype; +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; AfterInstall: RefreshEnvironment; Components: JDK; \ + ValueName: "JAVA_HOME"; ValueData: "{app}\jdk"; Flags: uninsdeletevalue ; +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; AfterInstall: RefreshEnvironment; Components: JDK; \ + ValueName: "JDK_21"; ValueData: "{app}\jdk"; Flags: uninsdeletevalue ; -; 【Redis】追加到 PATH 变量 -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: Redis; \ - ValueName: "Path"; ValueData: "{olddata};%X_COMMAND%\redis"; Check: NeedsAddPath('%X_COMMAND%\redis'); +;; 【Redis】追加到 PATH 变量 +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; AfterInstall: RefreshEnvironment; Components: Redis; \ + ValueName: "Path"; ValueData: "{olddata};%X_COMMAND%\redis"; Check: NeedsAddPath('%X_COMMAND%\redis'); Flags: uninsdeletevalue ; -; 【MinIO】追加到 PATH 变量 -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: MinIO; \ - ValueName: "Path"; ValueData: "{olddata};%X_COMMAND%\io"; Check: NeedsAddPath('%X_COMMAND%\io'); +;; 【MinIO】追加到 PATH 变量 +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; AfterInstall: RefreshEnvironment; Components: MinIO; \ + ValueName: "Path"; ValueData: "{olddata};%X_COMMAND%\io"; Check: NeedsAddPath('%X_COMMAND%\io'); Flags: uninsdeletevalue ; -; 【Nginx】追加到 PATH 变量 -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: Nginx; \ - ValueName: "Path"; ValueData: "{olddata};%X_COMMAND%\nginx"; Check: NeedsAddPath('%X_COMMAND%\nginx'); +;; 【Nginx】追加到 PATH 变量 +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; AfterInstall: RefreshEnvironment; Components: Nginx; \ + ValueName: "Path"; ValueData: "{olddata};%X_COMMAND%\nginx"; Check: NeedsAddPath('%X_COMMAND%\nginx'); Flags: uninsdeletevalue ; -; 【RocketMQ】追加到 PATH 变量 -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: RocketMQ; \ - ValueName: "ROCKETMQ_HOME"; ValueData: "{app}\rocketmq"; Check: CheckRegistryPath('{app}\rocketmq'); -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: RocketMQ; \ - ValueName: "ROCKETMQ_SBIN"; ValueData: "{app}\rocketmq\sbin"; -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: RocketMQ; \ - ValueName: "Path"; ValueData: "{olddata};%ROCKETMQ_SBIN%"; Check: NeedsAddPath('%ROCKETMQ_SBIN%'); +;; 【RocketMQ】追加到 PATH 变量 +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; AfterInstall: RefreshEnvironment; Components: RocketMQ; \ + ValueName: "ROCKETMQ_HOME"; ValueData: "{app}\rocketmq"; Check: CheckRegistryPath('{app}\rocketmq'); Flags: uninsdeletevalue ; +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; AfterInstall: RefreshEnvironment; Components: RocketMQ; \ + ValueName: "ROCKETMQ_SBIN"; ValueData: "{app}\rocketmq\sbin"; Flags: uninsdeletevalue ; +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; AfterInstall: RefreshEnvironment; Components: RocketMQ; \ + ValueName: "Path"; ValueData: "{olddata};%ROCKETMQ_SBIN%"; Check: NeedsAddPath('%ROCKETMQ_SBIN%'); Flags: uninsdeletevalue ; -; 【MySQL】环境变量(注册服务使用) +;; 【MySQL】环境变量【注册服务使用】 ; 数据库服务注册后服务名 -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: MySQL; \ - ValueName: "X_MANAGE_DB_SC"; ValueData: "x_database"; +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; AfterInstall: RefreshEnvironment; Components: MySQL; \ + ValueName: "X_MANAGE_DB_SC"; ValueData: "x_database"; Flags: uninsdeletevalue ; ; 这两个值,将作为后续判断程序是否已经安装做依据 -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: MySQL; \ - ValueName: "X_MANAGE_DB_EXE"; ValueData: "{app}\mysql\bin\mysqld.exe"; -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: MySQL; \ - ValueName: "X_MANAGE_DB_COF"; ValueData: "{app}\mysql\my.ini"; +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; AfterInstall: RefreshEnvironment; Components: MySQL; \ + ValueName: "X_MANAGE_DB_EXE"; ValueData: "{app}\mysql\bin\mysqld.exe"; Flags: uninsdeletevalue ; +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; AfterInstall: RefreshEnvironment; Components: MySQL; \ + ValueName: "X_MANAGE_DB_COF"; ValueData: "{app}\mysql\my.ini"; Flags: uninsdeletevalue ; -; MySQL(通用服务),导入脚本数据使用 -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: MySQL; \ - ValueName: "X_COMMAND_MYSQL"; ValueData: "{app}\mysql\"; +; MySQL【通用服务】,导入脚本数据使用 +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; AfterInstall: RefreshEnvironment; Components: MySQL; \ + ValueName: "X_COMMAND_MYSQL"; ValueData: "{app}\mysql\"; Flags: uninsdeletevalue ; ; 追加到 PATH 变量 -Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; Flags: preservestringtype; AfterInstall: RefreshEnvironment; Components: MySQL; \ - ValueName: "Path"; ValueData: "{olddata};%X_COMMAND_MYSQL%\bin"; Check: NeedsAddPath('%X_COMMAND_MYSQL%\bin'); +Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; AfterInstall: RefreshEnvironment; Components: MySQL; \ + ValueName: "Path"; ValueData: "{olddata};%X_COMMAND_MYSQL%\bin"; Check: NeedsAddPath('%X_COMMAND_MYSQL%\bin'); Flags: uninsdeletevalue ; + ;; 自定义函数 @@ -183,6 +198,9 @@ const WM_SETTINGCHANGE = 26; // 0x001A 的十进制 SMTO_ABORTIFHUNG = 2; // 0x0002 的十进制 + // 定义 VC++ 2019 运行时的注册表检查路径 + VC2019_REDIST_X64 = '{FF66E9F6-83E7-3A3E-AF14-8DE9A809A6A4}'; + VC2019_REDIST_X86 = '{422B21A3-06FA-3F2F-A6C6-21BCC9B8E2F3}'; function SendMessageTimeout( hWnd: Integer; @@ -256,6 +274,40 @@ begin end; +// 检查是否已安装 VC++ 2019 运行时 +function IsVC2019Installed: Boolean; +var + Version: String; +begin + // 检查64位版本 + Result := RegQueryStringValue( + HKLM, + 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64', + 'Version', + Version + ) or RegKeyExists( + HKLM, + 'SOFTWARE\Classes\Installer\Dependencies\' + VC2019_REDIST_X64 + ); + + // 如果是32位系统或需要检查32位运行时 + if not Result and (not IsWin64) then + Result := RegQueryStringValue( + HKLM, + 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86', + 'Version', + Version + ) or RegKeyExists( + HKLM, + 'SOFTWARE\Classes\Installer\Dependencies\' + VC2019_REDIST_X86 + ); +end; + + + + + + // 从模板创建配置文件 procedure CreateConfigFromTemplate; var @@ -324,6 +376,26 @@ begin end; + + + + + +// 在安装前检查 +function InitializeSetup: Boolean; +begin + // 默认允许安装继续 + Result := True; + // 如果 VC++ 2019 未安装 + if not IsVC2019Installed then + begin + MsgBox('本程序需要 Microsoft Visual C++ 2019 运行时才能继续(1001)', mbError, MB_OK) + // 中止安装 + Result := False; + end; +end; + + // 在安装完成后执行 procedure CurStepChanged(CurStep: TSetupStep); begin