;iss #define MyAppName "基础环境" #define MyAppVersion "v1.0.0" #define MyAppPublisher "X" #define MyAppURL "~" #define MyAppExeName "command" #define MyAppAssocName MyAppName + " File" #define MyAppAssocExt ".myp" #define MyAppAssocKey StringChange(MyAppAssocName, " ", "") + MyAppAssocExt ; 默认配置 [Setup] AppId={{517C2278-C7C9-43D0-8E94-BFD2039C7BB8} ; 默认安装路径 DefaultDirName={localappdata}\XManage ; 是否加密 ;Encryption=yes ; 安装密码 ;Password=20250801 ; ICO图标 ; SetupIconFile=Resources\startup.ico UninstallFilesDir={app} UninstallDisplayIcon={app}\{#MyAppExeName}.exe VersionInfoCompany= VersionInfoCopyright=CopyRight © 2025 VersionInfoDescription= VersionInfoProductVersion=1.0.0 VersionInfoProductName=基础环境(支持Windows7及以上) ; 默认配置 AppName={#MyAppName} AppVersion={#MyAppVersion} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} AppUpdatesURL={#MyAppURL} ChangesAssociations=yes DisableDirPage=no DisableProgramGroupPage=no Compression=lzma2 SolidCompression=yes WizardStyle=modern ChangesEnvironment=yes PrivilegesRequired=admin ArchitecturesAllowed=x64compatible ArchitecturesInstallIn64BitMode=x64compatible OutputDir=Release\ OutputBaseFilename=Setup-{#MyAppVersion} ; 语言选择 [Languages] Name: "Chinese"; MessagesFile: "compiler:Languages\Chinese.isl" ;; 组件安装方式 [Types] Name: "full"; Description: "完整组件安装" Name: "custom"; Description: "自定义组件安装" ;; 组件列表选择项 [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 ;; 引入文件列表 [Files] ;; 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\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 ;; 创建必要目录 [Dirs] Name: "{app}\nginx\dist"; Permissions: users-modify ;; 安装前后删除文件 [InstallDelete] Type: files; Name: "{app}\mysql\template*.bat"; Type: files; Name: "{app}\mysql\start-mysql-demo.bat"; 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")}" ; 默认注册信息 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""" ;; 【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'); ; 【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"; ; 【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'); ; 【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'); ; 【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'); ; 【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%'); ; 【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; 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"; ; 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\"; ; 追加到 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'); ;; 自定义函数 [Code] const WM_SETTINGCHANGE = 26; // 0x001A 的十进制 SMTO_ABORTIFHUNG = 2; // 0x0002 的十进制 function SendMessageTimeout( hWnd: Integer; Msg: Integer; wParam: Integer; lParamStr: String; fuFlags: Integer; uTimeout: Integer; var lpdwResult: Integer ): Integer; external 'SendMessageTimeoutW@user32.dll stdcall'; // 给 Path 系统环境变量追加环境 function NeedsAddPath(Param: string): boolean; var OrigPath: string; begin if not RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', OrigPath) then begin Result := True; exit; end; // 检查路径是否已存在 Result := Pos(';' + Param + ';', ';' + OrigPath + ';') = 0; if Result = True then Result := Pos(';' + Param + '\;', ';' + OrigPath + ';') = 0; end; // 刷新系统环境 procedure RefreshEnvironment; var Res: Integer; begin SendMessageTimeout( HWND_BROADCAST, WM_SETTINGCHANGE, 0, 'Environment', SMTO_ABORTIFHUNG, 5000, Res ); end; // 检查环境变量,路径是否存在空格 function CheckRegistryPath(Path: string): Boolean; begin if Pos(' ', Path) > 0 then begin SuppressibleMsgBox('安装程序错误: 检测到无效的注册表路径 "' + Path + '"。路径不能包含空格。', mbCriticalError, MB_OK, IDOK); Abort; Result := False; Exit; end; Result := True; end; // 以 UTF-8 写入文件 function SaveStringToUTF8File(const FileName, Content: String; Append: Boolean): Boolean; var UTF8Content: AnsiString; begin UTF8Content := UTF8Encode(Content); Result := SaveStringToFile(FileName, UTF8Content, Append); end; // 从模板创建配置文件 procedure CreateConfigFromTemplate; var // ini TemplateIniPath: String; TargetIniPath: String; // initial TemplateInitialPath: String; TargetInitialPath: String; // register TemplateRegisterPath: String; TargetRegisterPath: String; // handle params ConfigLines: TArrayOfString; I: Integer; ReplaceCount: Integer; begin // generate my.ini TemplateIniPath := ExpandConstant('{app}\mysql\template.ini'); TargetIniPath := ExpandConstant('{app}\mysql\my.ini'); if LoadStringsFromFile(TemplateIniPath, ConfigLines) then begin for I := 0 to GetArrayLength(ConfigLines)-1 do begin StringChangeEx(ConfigLines[I], '%INSTALLPATH%', ExpandConstant('{app}\mysql'), True); StringChangeEx(ConfigLines[I], '%DATAPATH%', ExpandConstant('{app}\mysql\data'), True); StringChangeEx(ConfigLines[I], '\', '\\', True); end; SaveStringsToFile(TargetIniPath, ConfigLines, False); end; // generate initialize-and-start-mysql.bat TemplateInitialPath := ExpandConstant('{app}\mysql\template-initialize-and-start-mysql.bat'); TargetInitialPath := ExpandConstant('{app}\mysql\initialize-and-start-mysql.bat'); if LoadStringsFromFile(TemplateInitialPath, ConfigLines) then begin for I := 0 to GetArrayLength(ConfigLines)-1 do begin StringChangeEx(ConfigLines[I], '%INSTALLPATH%', ExpandConstant('{app}\mysql'), True); end; SaveStringsToFile(TargetInitialPath, ConfigLines, False); end; // generate register-mysql-with-data.bat TemplateRegisterPath := ExpandConstant('{app}\mysql\template-register-mysql-with-data.bat'); TargetRegisterPath := ExpandConstant('{app}\mysql\register-mysql-with-data.bat'); if LoadStringsFromFile(TemplateRegisterPath, ConfigLines) then begin for I := 0 to GetArrayLength(ConfigLines)-1 do begin StringChangeEx(ConfigLines[I], '%INSTALLPATH%', ExpandConstant('{app}\mysql'), True); end; SaveStringsToFile(TargetRegisterPath, ConfigLines, False); end; end; // 在安装完成后执行 procedure CurStepChanged(CurStep: TSetupStep); begin if CurStep = ssPostInstall then begin CreateConfigFromTemplate; // if UsingWinNT then // Exec('cmd.exe', '/C cmd', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); end; end; // 卸载前先停止程序运行 procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); begin if CurUninstallStep = usUninstall then begin // 在这里执行你的脚本或程序 // Exec(ExpandConstant('{cmd}'), '/C "uninstall_script.bat"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); end; end; [UninstallRun] ;; 卸载前运行 Filename: "sc"; Parameters: "stop redis"; Flags: runascurrentuser runhidden waituntilterminated Filename: "sc"; Parameters: "delete redis"; Flags: runascurrentuser runhidden waituntilterminated Filename: "sc"; Parameters: "stop x_database"; Flags: runascurrentuser runhidden waituntilterminated Filename: "sc"; Parameters: "delete x_database"; Flags: runascurrentuser runhidden waituntilterminated ;; 卸载时删除的文件 [UninstallDelete] Type: files; Name: "{app}\mysql\my.ini" Type: files; Name: "{app}\mysql\*.bat" Type: filesandordirs; Name: "{app}\mysql\data"