WindowsStarter/base/install_all.iss
2025-08-26 16:15:34 +08:00

730 lines
26 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;iss
#define MyAppName "基础环境"
#define MyAppVersion "1.0.14"
#define MyAppPublisher "X"
#define MyAppURL "~"
#define MyAppExeName "command"
#define MyAppExeNameHump "Command"
#define MyAppExeNameUpper "COMMAND"
#define MyAppAssocName MyAppName + " File"
#define MyAppAssocExt ".myp"
#define MyAppAssocKey StringChange(MyAppAssocName, " ", "") + MyAppAssocExt
#define MyAppFirstPath "XManage"
#define MyAppResources "Resources"
#define InstallPassword GetDateTimeString('yyyymmdd', '', '')
#define BuildTime GetDateTimeString('yyyymmddhhnnss', '', '')
; 默认配置
[Setup]
; 不得复用每个应用必须有唯一AppId
AppId={{517C2278-C7C9-43D0-8E94-BFD2039C1690}
; 默认安装路径
DefaultDirName={localappdata}\{#MyAppFirstPath}
; 是否加密
;Encryption=yes
; 安装密码
;Password={#InstallPassword}
; ICO图标
; SetupIconFile=Resources\startup.ico
UninstallFilesDir={app}
UninstallDisplayIcon={app}\{#MyAppExeName}.exe
VersionInfoCompany=
VersionInfoCopyright=CopyRight © 2025
VersionInfoDescription=构建于 {#BuildTime}装配DB、IO、MQ、Command等
VersionInfoProductVersion={#MyAppVersion}
VersionInfoProductName=基础环境支持Windows7及以上
; 默认配置
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
ChangesAssociations=yes
DisableDirPage=no
DisableProgramGroupPage=yes
Compression=lzma2
SolidCompression=yes
WizardStyle=modern
ChangesEnvironment=yes
PrivilegesRequired=admin
ArchitecturesAllowed=x64compatible
ArchitecturesInstallIn64BitMode=x64compatible
OutputDir=Release\
OutputBaseFilename=RuntimeSetup-{#MyAppVersion}
; 语言选择
[Languages]
Name: "Chinese"; MessagesFile: "compiler:Languages\Chinese.isl";
;; 任务
[Tasks]
; 是否创建桌面图标
; checkablealone 默认选中
; unchecked 默认不选中
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkablealone
;; 程序 ICO
[Icons]
;Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}.exe"
Name: "{autodesktop}\Quick Start Environment"; Filename: "{app}\quick.bat"; Comment: "一键启动 Redis、MinIO、Home、RocketMQ 服务"; Tasks: desktopicon
;; 组件安装方式
[Types]
Name: "full"; Description: "完整组件安装";
Name: "mini"; Description: "最小安装";
;; ============================================== 自定义组件 必须启用 iscustom 作为 Flags ==============================================
; iscustom 开启自定义选项
Name: "custom"; Description: "自定义组件安装"; Flags: iscustom;
;; 组件列表选择项
[Components]
;; ============================================== 自定义组件的 Types 可以不参与任何固定式 ==============================================
Name: "MainApp"; Description: "{#MyAppName}主程序"; Types: full mini; Flags: checkablealone;
Name: "JDK"; Description: "JDK"; Types: full; Flags: checkablealone;
Name: "Redis"; Description: "Redis"; Types: full; Flags: checkablealone;
Name: "MinIO"; Description: "MinIO"; Types: full; Flags: checkablealone;
Name: "RocketMQ"; Description: "RocketMQ"; Types: full; Flags: checkablealone;
Name: "Nginx"; Description: "Nginx"; Types: full; Flags: checkablealone;
Name: "MySQL"; Description: "MySQL"; Types: full; Flags: checkablealone;
;; 引入文件列表
[Files]
;; ============================================== 共享文件 禁止使用 ignoreversion 作为 Flags ==============================================
;; Readme
; 安装完的 readme 信息
;Source: "{#MyAppResources}\Readme.md"; DestDir: "{app}"; Flags: isreadme;
;; 文件
Source: "{#MyAppResources}\grep.exe"; DestDir: "{app}\usr"; DestName: "grep.exe"; Flags: ignoreversion; Components: MainApp;
Source: "{#MyAppResources}\quick.bat"; DestDir: "{app}"; DestName: "quick.bat"; Flags: ignoreversion; Components: MainApp;
;; 文件夹
; recursesubdirs createallsubdirs 递归复制整个目录
Source: "{#MyAppResources}\usr\*"; DestDir: "{app}\usr\"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: MainApp;
; onlyifdoesntexist 当文件不存在时安装
Source: "{#MyAppResources}\jdk\*"; DestDir: "{app}\jdk\"; Flags: ignoreversion recursesubdirs createallsubdirs onlyifdoesntexist; Components: JDK;
Source: "{#MyAppResources}\redis\*"; DestDir: "{app}\redis\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: Redis;
Source: "{#MyAppResources}\io\*"; DestDir: "{app}\io\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: MinIO;
Source: "{#MyAppResources}\rocketmq\*"; DestDir: "{app}\rocketmq\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: RocketMQ;
Source: "{#MyAppResources}\nginx\*"; DestDir: "{app}\nginx\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: Nginx;
Source: "{#MyAppResources}\mysql\*"; DestDir: "{app}\mysql\"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs; Components: MySQL;
;; 创建必要目录
[Dirs]
Name: "{app}\nginx\logs"; Permissions: users-modify; Components: Nginx;
Name: "{app}\nginx\dist"; Permissions: users-modify; Components: Nginx;
;; 安装前后删除文件(存在不生效的可能,转为 code 实现)
[InstallDelete]
;Type: files; Name: "{app}\mysql\template.ini";
;Type: files; Name: "{app}\mysql\template-initialize-and-start-mysql.bat";
;Type: files; Name: "{app}\mysql\template-register-mysql-with-data.bat";
;; 安装时注册表与环境变量列表
[Registry]
; uninsdeletevalue 卸载时删除值
; uninsdeletekey 卸载时删除键
; preservestringtype 保留原值类型
;; ============================================== Path 禁止使用任何 *delete*、*remove* 作为 Flags 运行 ==============================================
;; 写入普通注册表项
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: 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、head、sort、ls、rm、xargs、rar、zip、tar、md5sum、sha1sum...】
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Components: MainApp; Flags: uninsdeletevalue; \
ValueName: "X_COMMAND"; ValueData: "{app}";
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; Components: MainApp; Flags: preservestringtype; AfterInstall: RefreshEnvironment; \
ValueName: "Path"; ValueData: "{olddata};%X_COMMAND%\usr"; Check: NeedsAddPath('%X_COMMAND%\usr');
;; 【Java】追加到 PATH 变量
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Components: JDK; \
ValueName: "JAVA_HOME"; ValueData: "{app}\jdk"; Flags: uninsdeletevalue ;
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Components: JDK; \
ValueName: "JDK_21"; ValueData: "{app}\jdk"; Flags: uninsdeletevalue ;
; 为了启用 java、jps、jar 命令
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; Components: JDK; Flags: preservestringtype; AfterInstall: RefreshEnvironment; \
ValueName: "Path"; ValueData: "{olddata};%JAVA_HOME%\bin"; Check: NeedsAddPath('%JAVA_HOME%\bin');
;; 【Redis】追加到 PATH 变量
;Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; Components: Redis; Flags: preservestringtype; AfterInstall: RefreshEnvironment; \
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; Components: MinIO; Flags: preservestringtype; AfterInstall: RefreshEnvironment; \
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; Components: Nginx; Flags: preservestringtype; AfterInstall: RefreshEnvironment; \
ValueName: "Path"; ValueData: "{olddata};%X_COMMAND%\nginx"; Check: NeedsAddPath('%X_COMMAND%\nginx');
;
; 关闭注册到环境变量,整体由一键启动脚本代为执行
;; 【RocketMQ】追加到 PATH 变量
; rocketmq 脚本必要参数
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Components: RocketMQ; Flags: uninsdeletevalue; \
ValueName: "ROCKETMQ_HOME"; ValueData: "{app}\rocketmq"; Check: CheckRegistryPath('{app}\rocketmq');
;Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Components: RocketMQ; Flags: uninsdeletevalue; \
ValueName: "ROCKETMQ_SBIN"; ValueData: "{app}\rocketmq\sbin";
;Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; Components: RocketMQ; Flags: preservestringtype; AfterInstall: RefreshEnvironment; \
ValueName: "Path"; ValueData: "{olddata};%ROCKETMQ_SBIN%"; Check: NeedsAddPath('%ROCKETMQ_SBIN%');
;
; 关闭注册到环境变量,整体由一键启动脚本代为执行
;; 【MySQL】环境变量【注册服务使用】
; 数据库服务注册后服务名
;Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Components: MySQL; Flags: uninsdeletevalue; AfterInstall: RefreshEnvironment; \
ValueName: "X_MANAGE_DB_SC"; ValueData: "x_database";
; 这两个值,将作为后续判断程序是否已经安装做依据
;Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Components: MySQL; Flags: uninsdeletevalue; AfterInstall: RefreshEnvironment; \
ValueName: "X_MANAGE_DB_EXE"; ValueData: "{app}\mysql\bin\mysqld.exe";
;Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Components: MySQL; Flags: uninsdeletevalue ; AfterInstall: RefreshEnvironment; \
ValueName: "X_MANAGE_DB_COF"; ValueData: "{app}\mysql\my.ini";
;
; 暂时关闭注册到环境变量,暂时由 bat 启动或直接注册到服务
; 上述环境变量是 ps1 启动时所需的必要参数,状态暂停,等待整理
; MySQL【通用服务】导入脚本数据使用
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; Components: MySQL; Flags: uninsdeletevalue; \
ValueName: "X_COMMAND_MYSQL"; ValueData: "{app}\mysql\";
; 追加到 PATH 变量where mysql 语法判定使用
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; Components: MySQL; Flags: preservestringtype; AfterInstall: RefreshEnvironment; \
ValueName: "Path"; ValueData: "{olddata};%X_COMMAND_MYSQL%\bin"; Check: NeedsAddPath('%X_COMMAND_MYSQL%\bin');
;; 自定义函数
[Code]
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}';
// 服务
SC_MANAGER_CONNECT = $0001;
SERVICE_STOP = $0020;
SERVICE_QUERY_STATUS = $0004;
SERVICE_CONTROL_STOP = $00000001;
// 获取安装密码
function GetInstallPassword(): string;
begin
Result := GetDateTimeString('yyyymmdd', '', '');
end;
// 获取当前时间
function GetDateTime(): String;
begin
// Result := GetDateTimeString('yyyy/mm/dd hh:nn:ss', '-', ':');
Result := GetDateTimeString('yyyymmddhhnnss', '', '');
end;
// 导入 Windows API 函数,作用于 延迟函数
function GetTickCount: DWord;
external 'GetTickCount@kernel32.dll stdcall';
// 导入 Windows API 函数,作用于 环境变量更新
function SendMessageTimeout(
hWnd: Integer;
Msg: Integer;
wParam: Integer;
lParamStr: String;
fuFlags: Integer;
uTimeout: Integer;
var lpdwResult: Integer
): Integer;
external 'SendMessageTimeoutW@user32.dll stdcall';
// 导入必要的 Windows API 函数,作用于 服务
function OpenService(
hSCManager: Longword;
lpServiceName: string;
dwDesiredAccess: Longword
): Longword;
external 'OpenServiceW@advapi32.dll stdcall';
// 导入必要的 Windows API 函数,作用于 服务
function ControlService(
hService: Longword;
dwControl: Longword;
var lpServiceStatus: Longword
): Integer;
external 'ControlService@advapi32.dll stdcall';
// 导入必要的 Windows API 函数,作用于 服务
function CloseServiceHandle(
hSCObject: Longword
): Integer;
external 'CloseServiceHandle@advapi32.dll stdcall';
// 导入必要的 Windows API 函数,作用于 服务
function OpenSCManager(
lpMachineName: string;
lpDatabaseName: string;
dwDesiredAccess: Longword
): Longword;
external 'OpenSCManagerW@advapi32.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;
// 检查是否已安装 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;
// 延迟n秒
procedure Delay(Seconds: Integer);
var
ResultCode: Integer;
begin
Exec(ExpandConstant('{cmd}'), '/C timeout /t ' + IntToStr(Seconds) + ' /nobreak > nul', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
end;
// 延迟n毫秒
procedure DelayMS(MS: Cardinal);
var
T: Cardinal;
begin
T := GetTickCount;
while (GetTickCount - T) < MS do
begin
// 处理消息队列,防止界面冻结
Sleep(10);
WizardForm.Refresh;
end;
end;
// InitializeSetup 安装程序初始化时 检查系统环境、前置条件
// InitializeWizard 向导初始化时 自定义界面、预设置
// CurStepChanged 安装步骤改变时 在特定步骤(如安装前、后)执行自定义操作
// DeinitializeSetup 安装结束时(无论成功与否) 清理临时文件、最终配置
// 从模板创建配置文件
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
// 生成 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;
// 生成 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;
// 生成 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 RemoveTempFile;
begin
// DeleteFile
// DelTree
// 删除模版文件
if FileExists(ExpandConstant('{app}\mysql\template.ini')) then
DeleteFile(ExpandConstant('{app}\mysql\template.ini'));
if FileExists(ExpandConstant('{app}\mysql\template-initialize-and-start-mysql.bat')) then
DelTree(ExpandConstant('{app}\mysql\template-initialize-and-start-mysql.bat'), False, True, False);
if FileExists(ExpandConstant('{app}\mysql\template-register-mysql-with-data.bat')) then
DelTree(ExpandConstant('{app}\mysql\template-register-mysql-with-data.bat'), False, True, False);
if FileExists(ExpandConstant('{app}\mysql\import-data-into-mysql-v2.bat')) then
DelTree(ExpandConstant('{app}\mysql\import-data-into-mysql-v2.bat'), False, True, False);
// 删除默认 Readme.md
if FileExists(ExpandConstant('{app}\io\Readme.md')) then
DeleteFile(ExpandConstant('{app}\io\Readme.md'));
if FileExists(ExpandConstant('{app}\jdk\Readme.md')) then
DeleteFile(ExpandConstant('{app}\jdk\Readme.md'));
if FileExists(ExpandConstant('{app}\mysql\Readme.md')) then
DeleteFile(ExpandConstant('{app}\mysql\Readme.md'));
if FileExists(ExpandConstant('{app}\nginx\Readme.md')) then
DeleteFile(ExpandConstant('{app}\nginx\Readme.md'));
end;
// 初始化并启动MySQL
procedure InitializeAndStartMySQL;
var
ResultCode: Integer;
Cmd: string;
begin
// 通过 mysql 初始化生成的唯一 uuid 判断 mysql 是否已经完成初始化
if not FileExists(ExpandConstant('{app}\mysql\data\auto.cnf')) then
begin
// 如果没有完成初始化,则判断是否存在 readme.md 文件 即完全没有初始化
if FileExists(ExpandConstant('{app}\mysql\data\Readme.md')) then
begin
// 如果没有初始化,则删除 readme
DelTree(ExpandConstant('{app}\mysql\data\Readme.md'), False, True, False);
DelayMS(200);
end;
// 存在默认库SQL压缩包
if FileExists(ExpandConstant('{app}\mysql\database.rar')) then
begin
// 解压
if not Exec('cmd.exe', '/C " cd ' + ExpandConstant('{app}') + '\mysql && %cd%\..\usr\unrar.exe x database.rar script\demo\"', '', SW_HIDE, ewNoWait, ResultCode) then
begin
MsgBox('解压 MySQL 默认库失败', mbError, MB_OK);
end;
// 删除 database.rar 默认库SQL压缩包
DelayMS(1000);
DelTree(ExpandConstant('{app}\mysql\database.rar'), False, True, False);
end;
DelayMS(1000);
// 初始化
// 同步 ewWaitUntilTerminated
// 异步 ewNoWait
// 初始化并启动 MySQL
// Cmd := '/C "' + ExpandConstant('{app}') + '\mysql\initialize-and-start-mysql.bat"';
Cmd := '/C " cd ' + ExpandConstant('{app}') + '\mysql && initialize.bat"';
if not Exec('cmd.exe', Cmd, '', SW_HIDE, ewNoWait, ResultCode) then
begin
MsgBox('初始化 MySQL 脚本失败', mbError, MB_OK);
end else begin
DelayMS(3000);
// DeleteFile(ExpandConstant('{app}\mysql\initialize-and-start-mysql.bat'));
DeleteFile(ExpandConstant('{app}\mysql\register-mysql-with-data.bat'));
// DeleteFile(ExpandConstant('{app}\mysql\initialize.bat'));
end;
DelayMS(1000);
end; // mysql auto.conf 初始化判定
end;
// 导入默认数据库到 MySQL
// procedure ImportDefaultDatabase2MySQL;
// var
// ResultCode: Integer;
// Cmd: string;
// MySQLPath: string;
// UsrPath: string;
// begin
//
// // 判断是否安装了 usr 基础环境
// if FileExists(ExpandConstant('{app}\usr\rar.exe')) then
// begin
//
// // 等待 MySQL 服务启动完成
// DelayMS(3000);
// // 这个时候 `环境变量` 还没开始注册,所以 bat 导入脚本不生效因此需要指定临时Path环境变量
// // 导出默认库和用户
// if FileExists(ExpandConstant('{app}\mysql\import-data-into-mysql.bat')) then
// begin
//
// // 临时设置 PATH 并执行脚本
// MySQLPath := ExpandConstant('{app}') + '\mysql\bin';
// UsrPath := ExpandConstant('{app}') + '\usr';
// Cmd := '/C "set PATH=' + MySQLPath + '; ' + UsrPath + ';%PATH%' +
// ' && cd ' + ExpandConstant('{app}') + '\mysql' +
// ' && import-data-into-mysql.bat"' +
// ' && exit"';
//
// if not Exec('cmd.exe', Cmd, '', SW_HIDE, ewNoWait, ResultCode) then
// begin
// MsgBox('初始化默认库脚本失败', mbError, MB_OK);
// end;
// DelayMS(1000);
// end;
// end; // 是否安装了 usr 环境
//
// 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
// 仅在安装完成后执行
if CurStep = ssPostInstall then
begin
// 创建配置文件
CreateConfigFromTemplate;
// 删除过程文件
RemoveTempFile;
// 初始化并启动 MySQL
InitializeAndStartMySQL;
// 导入默认数据库到 MySQL
// ImportDefaultDatabase2MySQL;
end; // 安装完成后的执行
end;
// 卸载前先停止程序运行
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
hSCManager, hService: Longword;
ServiceStatus: Longword;
ResultCode: Integer;
DataDir: string;
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
Filename: "taskkill"; Parameters: "-f -im home-web.exe"; Flags: runascurrentuser runhidden waituntilterminated
;; 卸载时删除的文件
[UninstallDelete]
; 删除 mysql 相关内容停止服务可能需要一定时间因此删除mysql时可能存在占用问题导致删除失败需要转到 code 实现)
Type: files; Name: "{app}\mysql\my.ini"
Type: files; Name: "{app}\mysql\*.bat"
Type: filesandordirs; Name: "{app}\mysql\data"
Type: filesandordirs; Name: "{app}\mysql\lib"
Type: filesandordirs; Name: "{app}\mysql\bin"
; 删除 minio 数据
Type: filesandordirs; Name: "{app}\io"
Type: filesandordirs; Name: "{app}\io\data"
; 删除 nginx log
Type: filesandordirs; Name: "{app}\nginx\logs"
; 删除 rocketmq 数据
Type: filesandordirs; Name: "{app}\rocketmq\sbin\store"