能否在Inno Setup卸载时按条件选择性删除文件?
Inno Setup 安装与自定义更新的卸载条件配置问题
场景说明
- 已实现安装程序的两种启动选项:正常安装和自定义更新
- 自定义更新本质为常规安装,需用户指定预安装路径(适配手动安装过Java、Tomcat及Web应用的用户)
- 已通过注册表项区分操作是通过「Installer」还是「Updater」选项完成
核心需求
- 正常安装的软件,卸载时删除所有文件
- 自定义更新的软件,卸载时仅删除卸载程序自身exe及关联数据文件,不删除
[Files]段中的其他文件 - 不能使用
uninsneveruninstall标识,需保留正常安装的完整卸载功能
问题
能否设置条件,让卸载程序仅在用户此前选择正常安装选项时,才删除[Files]部分的对应文件?
当前配置片段
[Setup] UninstallFilesDir={code:UnInstallerPath} [Files] Source: "<source>\Tomcat9\*"; DestDir: "{code:GetTomcatSourcepath}"; Excludes: "webapps"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "<source>\{#JAVA}\*"; DestDir: "{code:GetJAVAExtractpath}"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "<source>\Tomcat9\webapps\ROOT\*"; DestDir: "{code:GetWebAppSourcepath}"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "<source>\config\*"; DestDir: "{code:GetConfigInstallPath}"; Check: IsInstaller; Flags: ignoreversion recursesubdirs createallsubdirs Source: "<source>\libraries\{#DLLFile}"; DestDir: "{code:GetConfigInstallPath}"; Flags: ignoreversion [UninstallDelete] Type: filesandordirs; Name: "{code:GetUninstallPath}"; Check: IsInstalledviaProgram; Type: filesandordirs; Name: "{code:UnInstallerPath}";
解决方案
可以通过以下步骤实现需求:
注册表标记操作类型
在安装流程中,根据用户选择的是「Installer」还是「Updater」选项,写入对应的注册表项(例如HKLM\Software\你的应用名\InstallType,值设为Install或Update)。为
[Files]条目添加卸载判断条件
Inno Setup的[Files]条目支持UninstallCheck参数,用于控制该文件是否在卸载时被删除。编写脚本函数读取注册表值,判断是否为正常安装,以此决定是否删除文件。修改后的
[Files]段示例:[Files] Source: "<source>\Tomcat9\*"; DestDir: "{code:GetTomcatSourcepath}"; Excludes: "webapps"; Flags: ignoreversion recursesubdirs createallsubdirs; UninstallCheck: ShouldUninstallFile Source: "<source>\{#JAVA}\*"; DestDir: "{code:GetJAVAExtractpath}"; Flags: ignoreversion recursesubdirs createallsubdirs; UninstallCheck: ShouldUninstallFile Source: "<source>\Tomcat9\webapps\ROOT\*"; DestDir: "{code:GetWebAppSourcepath}"; Flags: ignoreversion recursesubdirs createallsubdirs; UninstallCheck: ShouldUninstallFile Source: "<source>\config\*"; DestDir: "{code:GetConfigInstallPath}"; Check: IsInstaller; Flags: ignoreversion recursesubdirs createallsubdirs; UninstallCheck: ShouldUninstallFile Source: "<source>\libraries\{#DLLFile}"; DestDir: "{code:GetConfigInstallPath}"; Flags: ignoreversion; UninstallCheck: ShouldUninstallFile编写
ShouldUninstallFile脚本函数
在[Code]段添加函数读取注册表,判断操作类型:[Code] function ShouldUninstallFile(): Boolean; var InstallType: String; begin // 替换为你实际的注册表路径 if RegQueryStringValue(HKLM, 'Software\你的应用名', 'InstallType', InstallType) then begin // 正常安装返回True(删除文件),更新操作返回False(保留文件) Result := (InstallType = 'Install'); end else begin // 默认按正常安装处理,删除文件 Result := True; end; end; // 安装时写入注册表的逻辑示例 procedure CurStepChanged(CurStep: TSetupStep); var IsUpdater: Boolean; begin if CurStep = ssPostInstall then begin // IsUpdater为你判断用户选择更新选项的变量 if IsUpdater then RegWriteStringValue(HKLM, 'Software\你的应用名', 'InstallType', 'Update') else RegWriteStringValue(HKLM, 'Software\你的应用名', 'InstallType', 'Install'); end; end;保留现有卸载程序删除逻辑
原[UninstallDelete]段中关于卸载程序自身的删除条目无需修改,确保更新操作卸载时能正常删除卸载程序及关联数据。
内容的提问来源于stack exchange,提问作者Holt
相关产品推荐
相关产品推荐

