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

问题描述 投票:0回答:1

所以,我意识到这个问题以前已经被问过。事实上,在写这篇文章之前,我读了其中的 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: 我希望安装程序覆盖或删除应用程序目录中的所有文件,包含用户数据的一个文件夹除外。

inno-setup
1个回答
0
投票

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

如您所知,您可以使用

[InstallDelete]
部分 来实现这一点。但这不允许您排除“数据”文件夹。

您可以编写 Pascal 脚本来代替。请参阅Inno Setup - 删除除数据子目录之外的整个应用程序文件夹。您可以从我对

DelTreeExceptSavesDir
 事件函数的问题的回答中调用 
CurStepChanged(ssInstall)
函数:

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:删除以前版本安装的文件

© www.soinside.com 2019 - 2024. All rights reserved.