Nano Hash - криптовалюты, майнинг, программирование

Inno Setup - удаление старых / устаревших файлов при обновлении

Итак, я понимаю, что этот вопрос задавался раньше. Фактически, я прочитал около 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: я хочу, чтобы установщик перезаписал или удалил все файлы в каталоге приложения, за исключением одной папки, содержащей данные пользователя.

02.07.2018

  • Итак, вы хотите удалить из установочной папки все файлы, которые не были установлены установщиком обновлений? 02.07.2018
  • Да, в значительной степени. Я добавил резюме в конце, чтобы прояснить это. 02.07.2018
  • Хотя связанный вопрос касается удаления, код в ответе также можно использовать в установщике. 02.07.2018
  • Похоже, он сначала все удалил, а потом все записал. Было бы неплохо, если бы удалялся только тот материал, который все равно не будет перезаписан. 02.07.2018
  • Это имеет значение только в том случае, если вы используете флаги, предотвращающие перезапись существующих файлов, если они уже существуют. Если безоговорочно перезаписывать файлы, то разницы не вижу. 02.07.2018
  • Например, меньшая нагрузка на жесткий диск / SSD. 02.07.2018
  • Почему? Если вы все равно перезаписываете файлы? 02.07.2018
  • Помог ли мой ответ? 12.07.2018
  • Нет, поскольку решение было развернуто 2 июля; мы просто включили небольшой исполняемый файл для запуска в конце установки, который сравнивает файл манифеста, с которым мы отправляем, все, что не входит в манифест, удаляется, а все, что в манифесте, проверяется контрольной суммой - может также. Я не смог ответить на вопрос сам, так как он был помечен как повторяющийся, и это, очевидно, делает это невозможным, поэтому я продолжил свою жизнь. 13.07.2018

Ответы:


1

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

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

Вместо этого вы можете закодировать этот Pascal Scripting. См. Раздел Inno Setup - удаление всей папки приложения, кроме подкаталога данных. Вы можете вызвать функцию DelTreeExceptSavesDir из моего ответа на этот вопрос из _3 _ функция события:

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

04.07.2018
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..