You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

InnoSetup补丁重命名安装目录后全量包无法识别卸载配置咨询

解决方案

问题本质

你遇到的问题核心是补丁包重命名安装目录后,没有同步更新Inno Setup写入注册表的卸载记录、安装路径缓存,导致后续全量包读取的还是旧的目录信息。

第一步:修改补丁包ISS配置

1. 优化重命名逻辑,同步更新注册表

把你补丁包原来的CurStepChanged方法替换为以下代码:

procedure CurStepChanged(CurStep: TSetupStep);
var
  sUnInstPath: string;
  sNewAppDir: string;
  sUninstallExePath: string;
  bIsHKLM: Boolean;
begin
   if (CurStep=ssPostInstall) then begin
    // 拼接新目录路径
    sNewAppDir := ExpandConstant('{app}\..\{#MyAppName} {#MyAppVersion}');
    // 执行目录重命名
    RenameFile(ExpandConstant('{app}'), sNewAppDir);
    
    // 确定卸载注册表路径
    sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1');
    // 先判断是HKLM还是HKCU的注册表
    bIsHKLM := RegValueExists(HKLM, sUnInstPath, 'UninstallString');
    
    // 拼接新的卸载程序路径
    sUninstallExePath := sNewAppDir + '\unins000.exe';
    
    // 更新卸载注册表项
    if bIsHKLM then begin
      RegWriteStringValue(HKLM, sUnInstPath, 'UninstallString', '"' + sUninstallExePath + '"');
      RegWriteStringValue(HKLM, sUnInstPath, 'InstallLocation', sNewAppDir);
      RegWriteStringValue(HKLM, sUnInstPath, 'DisplayIcon', sUninstallExePath + ',0');
    end else begin
      RegWriteStringValue(HKCU, sUnInstPath, 'UninstallString', '"' + sUninstallExePath + '"');
      RegWriteStringValue(HKCU, sUnInstPath, 'InstallLocation', sNewAppDir);
      RegWriteStringValue(HKCU, sUnInstPath, 'DisplayIcon', sUninstallExePath + ',0');
    end;
   end;
end;

2. 保留原有[UninstallDelete]配置

你现有配置无需修改,因为卸载程序运行时{app}对应的已经是更新后的新目录路径,会正确删除对应版本目录。

第二步:优化全量包ISS配置

你原来的卸载逻辑不用大改,只需要做两处调整:

  1. 在[Setup]段设置UsePreviousAppDir=false,卸载旧版本后全量包会自动创建符合规则的应用名 x.x.0新目录,不会出现目录冲突。
  2. 如果你需要默认安装路径和旧版本同父目录,可以在InitializeWizard事件中读取旧版本的安装路径,自动设置全量包的默认安装父目录:
procedure InitializeWizard();
var
  sUnInstPath: string;
  sOldInstallLoc: string;
  sNewDefaultDir: string;
begin
  sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1');
  // 读取旧版本安装路径
  if not RegQueryStringValue(HKLM, sUnInstPath, 'InstallLocation', sOldInstallLoc) then
    RegQueryStringValue(HKCU, sUnInstPath, 'InstallLocation', sOldInstallLoc);
  
  if sOldInstallLoc <> '' then begin
    // 取旧路径的父目录,拼接全量包的新目录名
    sNewDefaultDir := ExtractFileDir(sOldInstallLoc) + '\{#MyAppName} {#MyAppVersion}';
    WizardForm.DirEdit.Text := sNewDefaultDir;
  end;
end;

注意事项

  • 全量包和补丁包必须使用完全相同的AppId,才能读取到同一条卸载注册表记录
  • 重命名目录前确保没有应用进程在运行,避免重命名失败,可以在ssInstall步骤先杀掉应用进程
  • 如果是64位应用,需要在[Setup]段添加ArchitecturesInstallIn64BitMode=x64,避免注册表重定向导致读取不到卸载项

内容的提问来源于stack exchange,提问作者kzaiwo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 05:45:02