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

在Inno Setup中指定uninsdeletekey后如何保留注册表项

解决Inno Setup跨版本升级时注册表项丢失问题

问题背景

我在Inno Setup安装器中配置了uninsdeletekey标记:

Root: "HKA"; Subkey: "Software\Company\Application"; Flags: uninsdeletekey

目前为同一程序制作了32位和64位两个安装包,升级流程会先卸载旧版本,此时用户数据得以保留,但上述注册表项会被完全清除。由于无法修改卸载程序,且卸载器命令行开关无阻止清除的选项,需要通过其他方式规避注册表丢失问题。

方案演进

初始方案

  • 用定制工具以原始用户账号导出目标注册表项
  • 卸载旧应用
  • 安装新应用
  • 用定制工具以原始用户账号导入注册表项

优化后的方案(基于reg.exe)

  • 以原始用户账号运行reg.exe导出注册表项到文件
  • 卸载旧应用
  • 安装新应用
  • 新应用启动时检测导出文件,存在则调用reg.exe导入

已验证第一步可行性,测试代码如下(Pascal脚本):

ExecAsOriginalUser(ExpandConstant('{sys}\reg.exe'), 
    'export "HKEY_CURRENT_USER\Software\Company\Application" "d:\test.txt"', 
    '', SW_HIDE, ewWaitUntilTerminated, ExportRegResult);
Log(SysErrorMessage(ExportRegResult));

当前问题:代码中硬编码了导出路径d:\test.txt,需要优雅的方式获取临时文件名,并在安装完成后将其复制到用户数据文件夹。

优雅解决方案

1. 生成临时导出文件

利用Inno Setup内置的GetTempFileName函数生成临时文件路径,避免硬编码,同时指定.reg后缀便于识别:

var
  TempRegFile: String; // 声明为全局变量,供后续步骤调用
begin
  TempRegFile := GetTempFileName('.reg');
  ExecAsOriginalUser(ExpandConstant('{sys}\reg.exe'), 
      Format('export "HKEY_CURRENT_USER\Software\Company\Application" "%s"', [TempRegFile]), 
      '', SW_HIDE, ewWaitUntilTerminated, ExportRegResult);
  
  if ExportRegResult = 0 then
    Log('注册表导出成功,临时文件:' + TempRegFile)
  else
    Log('注册表导出失败:' + SysErrorMessage(ExportRegResult));
end;

2. 复制临时文件到用户数据目录

在安装完成阶段(ssPostInstall),将临时文件复制到用户数据目录,先确保目标目录存在:

procedure CurStepChanged(CurStep: TSetupStep);
var
  UserDataDir: String;
  DestRegFile: String;
begin
  if CurStep = ssPostInstall then
  begin
    UserDataDir := ExpandConstant('{userappdata}\Company\Application');
    ForceDirectories(UserDataDir); // 确保用户数据目录存在
    DestRegFile := UserDataDir + '\settings.reg';
    
    if FileExists(TempRegFile) then
    begin
      if CopyFile(TempRegFile, DestRegFile, False) then
      begin
        Log('临时注册表文件已复制到用户数据目录:' + DestRegFile);
        DeleteFile(TempRegFile); // 复制完成后清理临时文件
      end
      else
        Log('复制临时注册表文件失败');
    end;
  end;
end;

3. 应用启动时导入注册表

新应用启动时,检查用户数据目录下的settings.reg文件,若存在则执行导入,导入完成后可删除该文件避免重复操作:

reg.exe import "%APPDATA%\Company\Application\settings.reg"

注意事项

  • 需将TempRegFile声明为全局变量,确保导出步骤和后续复制步骤能正常访问
  • 全程需添加错误日志,便于排查导出、复制过程中出现的权限或文件问题
  • 基于{userappdata}的路径会自动适配当前用户,符合多用户场景需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:41:30