;iss #define MyAppName "基础环境" #define MyAppVersion "1.0.2" #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-BFD2039C7BB8} ; 默认安装路径 DefaultDirName={localappdata}\{#MyAppFirstPath} ; 是否加密 ;Encryption=yes ; 安装密码 ;Password={#InstallPassword} ; ICO图标 ; SetupIconFile=Resources\startup.ico UninstallFilesDir={app} UninstallDisplayIcon={app}\{#MyAppExeName}.exe VersionInfoCompany= VersionInfoCopyright=CopyRight © 2025 VersionInfoDescription=构建于 {#BuildTime},基本命令扩充(sed、awk、grep等) 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={#MyAppExeNameHump}Setup-{#MyAppVersion} ; 语言选择 [Languages] Name: "Chinese"; MessagesFile: "compiler:Languages\Chinese.isl"; ;; 任务 [Tasks] ; 是否创建桌面图标 ; checkablealone 默认选中 ; unchecked 默认不选中 ;Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked ;; 程序 ICO [Icons] ;Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}.exe" ;Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}.exe"; 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; ;; 引入文件列表 [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; ;; 文件夹 ; recursesubdirs createallsubdirs 递归复制整个目录 Source: "{#MyAppResources}\usr\*"; DestDir: "{app}\usr\"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: MainApp; ;; 创建必要目录 [Dirs] ;; 安装前后删除文件 [InstallDelete] ;; 安装时注册表与环境变量列表 [Registry] ; uninsdeletevalue 卸载时删除值 ; uninsdeletekey 卸载时删除键 ; preservestringtype 保留原值类型 ;; ============================================== Path 禁止使用任何 *delete*、*remove* 作为 Flags 运行 ============================================== ;; 【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_USR"; 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%\usr"; Check: NeedsAddPath('%X_COMMAND_USR%\usr'); ;; 自定义函数 [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}'; // 获取安装密码 function GetInstallPassword(): string; begin Result := GetDateTimeString('yyyymmdd', '', ''); end; 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; // 在安装前检查 function InitializeSetup: Boolean; begin // do somethings ... // 默认允许安装继续 Result := True; end; // 在安装完成后执行 procedure CurStepChanged(CurStep: TSetupStep); begin // 仅在安装完成后执行 if CurStep = ssPostInstall then begin // do somethings ... end; end; // 卸载前先停止程序运行 procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); begin if CurUninstallStep = usUninstall then begin // do somethings ... end; end; [UninstallRun] ;; 卸载前运行 ;; 卸载时删除的文件 [UninstallDelete]