Inno Setup - удаление старых / устаревших файлов при обновлении - PullRequest
0 голосов
/ 02 июля 2018

Итак, я понимаю, что этот вопрос задавался ранее. На самом деле я прочитал около 10 из них, прежде чем написать это, но ни у одного из них нет подходящего решения, и я надеюсь, что в настоящее время кто-то что-то нашел.

Проблема: Моя программа построена со скриптом, создающим все конечные файлы в одной папке. Эти файлы включены в Inno, как это:

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

Приложение было там в течение нескольких месяцев с различными обновлениями. Больше нет записей о старых файлах, хотя их можно тщательно собрать, так как у нас есть контроль версий, и я могу снова собрать старые установщики.

Из того, что я понимаю, вы должны использовать раздел InstallDelete, чтобы избавиться от старых файлов - однако вы не должны использовать подстановочные знаки, а также нет раздела Excludes для защиты единственной папки, которая у нас есть. которые могут содержать пользовательские данные, которые они могут захотеть сохранить.

Итак, как мне избавиться от старых файлов? Приложение имеет размер 100 МБ, и у текущего пользователя может быть более 300 МБ старых файлов, которые больше не нужны, я бы хотел это исправить.

TL; DR: Я хочу, чтобы установщик перезаписал или удалил все файлы в каталоге приложения, кроме одной папки, содержащей пользовательские данные.

1 Ответ

0 голосов
/ 04 июля 2018

Самое простое решение - удалить все файлы в папке установки перед установкой.

Как вы знаете, вы можете использовать [InstallDelete] секцию для этого. Но это не позволяет исключить папку «данные».

Вместо этого вы можете закодировать этот сценарий на Паскале. См. Inno Setup - Удалить всю папку приложения, кроме подкаталога данных . Вы можете вызвать функцию DelTreeExceptSavesDir из моего ответа на этот вопрос из CurStepChanged(ssInstall) функции события:

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

Если вы действительно хотите удалить только устаревшие файлы, чтобы избежать удаления и повторного создания существующих файлов (что является не вашим случаем , так как вы все равно используете флаг ignoreversion), вы можете использовать препроцессор для создайте список файлов, которые нужно установить для сценариев на Паскале, и используйте его для удаления только действительно устаревших файлов.

#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: удаление файлов, установленных предыдущей версией .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...