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

时间:2018-07-02 06:17:01

标签: inno-setup

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

1 个答案:

答案 0 :(得分:0)

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

如您所知,您可以使用[InstallDelete] section。但这不允许您排除“数据”文件夹。

您可以改为编写该Pascal脚本。参见Inno Setup - Delete whole application folder except for data subdirectory。您可以从我对CurStepChanged(ssInstall)事件函数的问题的回答中调用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: Removing files installed by previous version