Inno Setup中如何实现单文件夹安装及旧版本升级目录重命名?
从并行版本目录切换到单目录的Inno Setup升级方案
核心思路
无需先安装到旧版本目录再重命名,直接将新版本安装到无版本号的MySoftware目录即可。通过Inno脚本自动完成旧版本路径检测、用户配置迁移、旧版本静默卸载和残留目录清理,实现平滑升级。
具体实现步骤
1. 配置Setup段基础参数
给新版本分配独立的AppId(避免与旧版本冲突),指定默认安装目录为无版本号路径:
[Setup] AppId={你的新版本GUID} ; 必须与所有旧版本的AppId不同 AppName=MySoftware AppVersion=4.0 DefaultDirName={pf}\MySoftware DirExistsWarning=auto ; 自动处理目录已存在的情况 PrivilegesRequired=admin ; 如需安装到Program Files,保留此配置
2. 编写代码段实现旧版本检测与处理
在[Code]段中实现旧版本路径识别、配置迁移、旧版本卸载和目录清理逻辑:
var OldInstallPath: String; // 列出所有旧版本的AppId(每个并行版本对应一个唯一AppId) OldAppIdList: TArrayOfString; function InitializeSetup(): Boolean; var I: Integer; begin Result := True; OldAppIdList := ['{旧版本v2的AppId}', '{旧版本v3的AppId}']; OldInstallPath := ''; // 遍历检测旧版本的安装路径(先查HKLM,再查HKCU) for I := 0 to GetArrayLength(OldAppIdList) - 1 do begin if RegQueryStringValue(HKLM, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + OldAppIdList[I] + '_is1', 'InstallLocation', OldInstallPath) then Break; if RegQueryStringValue(HKCU, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + OldAppIdList[I] + '_is1', 'InstallLocation', OldInstallPath) then Break; end; end; procedure CurStepChanged(CurStep: TSetupStep); var UninstallExe: String; ErrorCode: Integer; ConfigPath: String; begin // 安装完成后执行旧版本处理逻辑 if CurStep = ssPostInstall then begin if OldInstallPath <> '' then begin // 1. 迁移用户配置文件(根据实际需要调整文件名) ConfigPath := OldInstallPath + '\config.ini'; if FileExists(ConfigPath) then begin CopyFile(ConfigPath, ExpandConstant('{app}\config.ini'), False); end; // 2. 静默卸载旧版本 UninstallExe := OldInstallPath + '\unins000.exe'; if FileExists(UninstallExe) then begin Exec(UninstallExe, '/silent /norestart', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode); end; // 3. 清理旧目录残留 if DirectoryExists(OldInstallPath) then begin RemoveDir(OldInstallPath); end; end; end; end;
3. 特殊场景适配
- 旧版本非Inno安装:如果旧版本不是用Inno Setup打包的,可修改
InitializeSetup函数,通过遍历{pf}下的MySoftware*格式目录来识别旧路径:function InitializeSetup(): Boolean; var FindRec: TFindRec; begin Result := True; OldInstallPath := ''; if FindFirst(ExpandConstant('{pf}\MySoftware*'), FindRec) then begin repeat if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY) <> 0 then begin OldInstallPath := ExpandConstant('{pf}\') + FindRec.Name; Break; end; until not FindNext(FindRec); FindClose(FindRec); end; end; - 多旧版本共存:如果用户同时安装了多个旧版本,可修改代码遍历所有找到的旧目录,逐个执行迁移、卸载和清理操作。
关键注意事项
- 新版本AppId必须与旧版本完全不同,确保安装程序能同时识别新旧版本,避免升级逻辑混乱。
- 迁移配置文件时,需确认文件路径和名称与旧版本一致,避免遗漏用户自定义设置。
- 测试时需覆盖全新安装、单旧版本升级、多旧版本共存升级等场景,确保流程稳定。
内容的提问来源于stack exchange,提问作者Waits321
相关产品推荐
相关产品推荐

