Inno Setup - 更新时删除旧的/过时的文件

2024-03-25

所以,我意识到这个问题以前已经被问过。事实上,在写这篇文章之前,我读了其中的 10 篇文章,但没有一个有适用的解决方案,我希望现在有人已经找到了一些东西。

问题: 我的程序是使用脚本构建的,在单个文件夹中创建所有最终文件。 这些文件包含在 inno 中,如下所示:

[Files]
Source: "build\exe.win-amd64-3.6\*"; Excludes: "*.key, *.log"; DestDir: "{app}"; \
    Flags: ignoreversion recursesubdirs createallsubdirs

该应用程序已经发布几个月了,并进行了不同的更新。不再有旧文件的记录,尽管可以费力地重新组装它,因为我们确实有版本控制,而且我可以再次构建旧的安装程序。

据我了解,你应该使用InstallDelete部分删除旧文件 - 但是您不应该使用通配符,而且也没有Excludes部分来保护我们拥有的可能包含他们可能想要保留的用户数据的单个文件夹。

那么,如何删除旧文件呢?该应用程序有 100 MB,当前用户可能有 300+ MB 不再需要的旧文件,我很乐意清理它们。

TL;DR:我希望安装程序覆盖或删除应用程序目录中的所有文件(包含用户数据的一个文件夹除外)。


最简单的解决方案是在安装之前删除安装文件夹中的所有文件。

如您所知,您可以使用[InstallDelete] section https://jrsoftware.org/ishelp/index.php?topic=installdeletesection为了那个原因。但这不允许您排除“数据”文件夹。

您可以改为编写 Pascal 脚本。看Inno Setup - 删除除数据子目录之外的整个应用程序文件夹 https://stackoverflow.com/q/36491213/850848。您可以致电DelTreeExceptSavesDir从我对这个问题的回答来看事件函数:

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssInstall then
  begin
    DelTreeExceptSavesDir(WizardDirValue); 
  end;
end;

如果您确实只想删除过时的文件,以避免删除和重新创建现有文件(什么是不是你的情况,当你使用ignoreversion无论如何标志),您可以使用预处理器生成要为 Pascal 脚本安装的文件列表,并使用它来仅删除真正过时的文件。

#pragma parseroption -p-

#define FileEntry(DestDir) \
    "  FilesNotToBeDeleted.Add('" + LowerCase(DestDir) + "');\n"

#define ProcessFile(Source, Dest, FindResult, FindHandle) \
    FindResult \
        ? \
            Local[0] = FindGetFileName(FindHandle), \
            Local[1] = Source + "\\" + Local[0], \
            Local[2] = Dest + "\\" + Local[0], \
            (Local[0] != "." && Local[0] != ".." \
                ? FileEntry(Local[2]) + \
                  (DirExists(Local[1]) ? ProcessFolder(Local[1], Local[2]) : "") \
                : "") + \
            ProcessFile(Source, Dest, FindNext(FindHandle), FindHandle) \
        : \
            ""

#define ProcessFolder(Source, Dest) \
    Local[0] = FindFirst(Source + "\\*", faAnyFile), \
    ProcessFile(Source, Dest, Local[0], Local[0])

#pragma parseroption -p+

[Code]

var
  FilesNotToBeDeleted: TStringList;

function InitializeSetup(): Boolean;
begin
  FilesNotToBeDeleted := TStringList.Create;
  FilesNotToBeDeleted.Add('\data');
  {#Trim(ProcessFolder('build\exe.win-amd64-3.6', ''))}
  FilesNotToBeDeleted.Sorted := True;

  Result := True;
end;

procedure DeleteObsoleteFiles(Path: string; RelativePath: string);
var
  FindRec: TFindRec;
  FilePath: string;
  FileRelativePath: string;
begin
  if FindFirst(Path + '\*', FindRec) then
  begin
    try
      repeat
        if (FindRec.Name <> '.') and (FindRec.Name <> '..') then
        begin
          FilePath := Path + '\' + FindRec.Name;
          FileRelativePath := RelativePath + '\' + FindRec.Name;
          if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then
          begin
            DeleteObsoleteFiles(FilePath, FileRelativePath);
          end;

          if FilesNotToBeDeleted.IndexOf(Lowercase(FileRelativePath)) < 0 then
          begin
            if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then
            begin
              if RemoveDir(FilePath) then
              begin
                Log(Format('Deleted obsolete directory %s', [FilePath]));
              end
                else
              begin
                Log(Format('Failed to delete obsolete directory %s', [FilePath]));
              end;
            end
              else
            begin
              if DeleteFile(FilePath) then
              begin
                Log(Format('Deleted obsolete file %s', [FilePath]));
              end
                else
              begin
                Log(Format('Failed to delete obsolete file %s', [FilePath]));
              end;
            end;
          end;
        end;
      until not FindNext(FindRec);
    finally
      FindClose(FindRec);
    end;
  end
    else
  begin
    Log(Format('Failed to list %s', [Path]));
  end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssInstall then
  begin
    Log('Looking for obsolete files...');
    DeleteObsoleteFiles(WizardDirValue, '');
  end;
end;

对于其他选项,请参见Inno Setup:删除以前版本安装的文件 https://stackoverflow.com/q/46007792/850848.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Inno Setup - 更新时删除旧的/过时的文件 的相关文章

  • inno-setup 脚本中的可选组件和类型

    我创建了以下 InnoSetup 脚本 用于添加可选组件 遵循此 StackOverflow 答案的建议 Inno Setup 正确使用 类型 组件 和 任务 https stackoverflow com questions 889082
  • 如何在 Inno Setup 中使用变量\宏?

    我尝试按以下方式使用宏 变量 但随后出现错误 你能给建议吗 define AnnotateDir C Users new skin Annotate project define AnnotateUserInstallAppData use
  • UTF-8 字符在 Inno Setup 中无法正确显示

    我已经看到了有关此问题的其他几个线程 但我花了一段时间试图对其进行排序 但无济于事 这是我的 iss 文件的通用版本 Script generated by the Inno Setup Script Wizard SEE THE DOCU
  • 注册表部分的脚本功能

    我们的软件支持一系列 70 文件关联 用户可以选择与我们的应用程序关联 直接在Registry安装程序部分并使用标志来控制卸载期间的行为以及Check标志来控制是否应将其写入注册表 用户可以通过自定义页面控制要设置的关联CheckListB
  • 为 Inno Setup 执行的 Postgres (psql) 进程设置 PGPASSWORD 环境变量

    我需要创建一个 PostgreSQL表空间 https www postgresql org docs current manage ag tablespaces html with 创新设置 https jrsoftware org is
  • 在 Inno Setup 中禁用静默和非常静默卸载

    是否可以在 Inno Setup 中禁用静默和非常静默卸载 您不能直接禁用它 但您可以检查它是否以静默模式运行并在运行期间显示消息 退出InitializeSetup InitialiseUninstall 事件函数 function In
  • Inno Setup:如果程序文件夹中存在文件,则关闭安装程序向导

    我正在尝试创建一个演示安装程序 如果它检测到该文件close txt在程序文件夹中 然后它会关闭向导或中止安装 我正在运行一个计划任务 该任务会在两天后自动卸载该应用程序 初次安装时close txt文件安装在程序文件夹中 然后自动卸载后c
  • 向标准 Inno Setup 页面添加额外的控件?

    如何将复选框添加到 Inno Setup 创建的文件夹选择对话框中 如下图所示 这不是自定义对话框 它是由 Inno Setup 自动创建的 Set the Parent复选框的属性WizardForm SelectDirPage var
  • 如何使用 Inno Setup 更改可执行文件权限?

    我通过 InnoIDE 中的向导创建了一个非常简单的 inno 脚本 但是 普通用户可以运行部署的可执行文件 如何强制用户必须通过脚本以管理员身份运行它 Setup AppId 03E6645E 2C53 4E90 967B D0833A8
  • 是否可以使用 INNO 脚本移动现有目录/文件?

    我们最近对一个使用 INNO 脚本安装的应用程序进行了重大重组 不幸的是 该应用程序需要某些文件在不同版本之间保持不变 更不幸的是 这些文件的位置在这次重组期间发生了变化 最不幸的是 现在由我来制作一个 INNO 脚本片段 它将查看这些文件
  • 将用户定义的命令行参数添加到/?窗户

    使用 Inno Setup 可以添加用户定义的命令行参数 当我使用 HELP命令中未列出用户定义的参数 如何将带有描述的命令添加到 HELP window Inno Setup 6 0 支持HelpTextNote message http
  • 准备卸载,就像 Inno Setup 中的准备安装页面一样

    我需要检查多个 exe 文件是否正在运行 通过安装程序安装 然后提示用户关闭它们 如果它们正在运行 如果没有则取消卸载过程 有没有办法在安装中为卸载程序提供类似 准备 页面之类的内容 或者我该如何实施这样的检查 甚至一个消息框也将是完美的
  • “ProgramData”目录的 Inno 设置常量

    我希望我的安装程序将一些文件复制到 Windows 中ProgramData目录中 我看到大多数 Windows 目录都有已在 Inno Setup 文档中定义的预定义常量 但是我看不到一个ProgramData 因此我计划使用类似的东西
  • 使用 wmi win32 类检查可用端口?

    我正在使用 inno setup 来制作安装文件 它需要提取本地 IP 地址 我可以通过查询 Win32 NetworkAdapterConfiguration 来完成 并检查特定端口是否打开以供软件运行 我目前正在寻找答案 我意识到 WM
  • Inno Setup - 允许用户选择“只有我”或“任何使用这台计算机的人”

    我遇到的一些安装程序让我选择 只为我 或 为 使用这台计算机的任何人 安装应用程序 如何让我的 Inno Setup 脚本向用户提供此选择 以便我可以根据他们的回答方式更改安装程序的操作 有很多方法可以解释 只有我 与 所有用户 问题的答案
  • 安装程序启动时间长 - 在 wpWelcome 之前添加对话框?

    我使用 Inno Setup 创建的安装程序大小约为 850 MB 包含约 7000 个文件和 890 个文件夹 未压缩大小为 1 98 GB 当开始安装过程时 之后Windows UAC 对话框出现后 安装程序的图标为空Taskbar约
  • 如何使用 Inno Setup 连接到 MS SQL Server?

    我想在安装过程中连接到 MS SQL Server 2008 有一个类似的问题 https stackoverflow com q 2171199 960757 它提供了一个解决方案 使用isql exe工具 与 SQL Server 20
  • 如何在 Inno Setup 中使用 GetVolumeInformation?

    我需要在使用 Inno Setup 创建的安装过程中获取驱动器号的卷序列号 我知道 DLL 函数可以导入到 Inno 中 但我对它还很陌生 并且在使其工作时遇到一些问题 我知道 kernel32 中的 GetVolumeInformatio
  • 在 Inno Setup 中添加 4 个许可证页面

    我遵循了马丁的回答here https stackoverflow com questions 34592002 how to create two licensefile pages in inno setup在我的 Inno Setup
  • 如何在 Inno Setup 中为控件卷出设置动画

    我想在我的安装程序中制作控件滚动的动画 你可以看这个视频 https drive google com file d 1H0HKTPXg9BdYD4HQWqCWHlGSTIHlcJa view 您可以使用计时器来为控件设置动画 Code f

随机推荐