Обновление установки InnoSetup — Обновление Директории предыдущей установки

#inno-setup

Вопрос:

Я создаю установщики как для полного приложения, так и для исправления.

Для полного установщика приложений (300 МБ ) управление версиями x.x.0 (например 1.1.0 ). И для патча (10 МБ ) это x.x.x (например 1.1.1 ).

Папка установки отформатирована следующим образом: «Имя приложения «. Пример — App Name 1.1.0 , App Name 1.1.1

На компьютере должна быть только 1 версия приложения, поэтому для установки полной версии — при обнаружении, что приложение было установлено ранее, сначала удаляется существующее приложение.

Итак, сценарий выглядит следующим образом:

  1. Пользователь устанавливает полное приложение — 1.1.0 (ОК)
    • Создается каталог App Name 1.1.0
  2. Пользователь устанавливает патч — 1.1.1 (ОК)
    • UsePreviousAppDir=true поэтому он пишет поверх каталога App Name 1.1.0
    • App Name 1.1.0 переименован в App Name 1.1.1 как часть CurStepChanged() when CurStep is ssPostInstall .
  3. Пользователь устанавливает полное приложение — 1.2.0 (ожидается, что NOK удалит предыдущую версию 1.1.1 и установит эту новую версию 1.2.0).
    • Если значение UsePreviousAppDir равно true, каталог App Name 1.1.0 будет создан. Это связано с тем, что Innosetup помнит это как «предыдущее приложение» (поскольку мы переименовали только патч).
    • Если значение UsePreviousAppDir равно false, App Name 1.2.0 создается каталог. И предыдущая версия App Name 1.1.1 не удаляется, потому что указывалась предыдущая установка App Name 1.1.0 .

Как я могу настроить свой файл ISS таким образом, чтобы при полной установке после установки исправления он все равно мог найти переименованный каталог и удалить его?

Для справки, вот мой код для переименования в установщике исправлений:

 { ///////////////////////////////////////////////////////////////////// } procedure CurStepChanged(CurStep: TSetupStep); begin  if (CurStep=ssPostInstall) then begin  RenameFile(ExpandConstant('{app}'), ExpandConstant('{app}..{#MyAppName} {#MyAppVersion}'))   end; end;  

И для моего сценария удаления (полная версия):

 { ///////////////////////////////////////////////////////////////////// } function GetUninstallString(): String; var  sUnInstPath: String;  sUnInstallString: String; begin  sUnInstPath := ExpandConstant('SoftwareMicrosoftWindowsCurrentVersionUninstall{#emit SetupSetting("AppId")}_is1');  sUnInstallString := '';  if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then  RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);  Result := sUnInstallString; end;   { ///////////////////////////////////////////////////////////////////// } function IsUpgrade(): Boolean; begin  Result := (GetUninstallString() lt;gt; ''); end;   { ///////////////////////////////////////////////////////////////////// } function UnInstallOldVersion(): Integer; var  sUnInstallString: String;  iResultCode: Integer; begin { Return Values: } { 1 - uninstall string is empty } { 2 - error executing the UnInstallString } { 3 - successfully executed the UnInstallString }   { default return value }  Result := 0;   { get the uninstall string of the old app }  sUnInstallString := GetUninstallString();  if sUnInstallString lt;gt; '' then begin  sUnInstallString := RemoveQuotes(sUnInstallString);  if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then  Result := 3  else  Result := 2;  end else  Result := 1; end;  { ///////////////////////////////////////////////////////////////////// } procedure CurStepChanged(CurStep: TSetupStep); begin  if (CurStep=ssInstall) then  begin  if (IsUpgrade()) then  begin  UnInstallOldVersion();  end;  end; end;  

И мой раздел [UninstallDelete] в установщике исправлений, на случай, если пользователь захочет удалить все это:

 [UninstallDelete] Type: filesandordirs; Name: "{app}..{#MyAppName} {#MyAppVersion}"  

Спасибо!

Комментарии:

1. Просто любопытно: важно ли, чтобы вы сохраняли номер версии в имени каталога? Вы разрешаете устанавливать только одну версию приложения за раз, так почему бы просто не использовать App Name и всегда сохранять каталог?

2. @PMF — Это очень важно, так как в наших предыдущих выпусках было такое соглашение об именах, и мы действительно не хотим его менять. В худшем случае, вероятно, это единственный вариант, который у нас есть, — удалить номер версии из каталога. Но, надеюсь, где-нибудь есть блестящая идея, где я мог бы сохранить версию.

3. Что делать, если при установке исправления вы также установите UsePreviousAppDir=false и выполните полную установку? Таким образом, он полностью удалит все и выполнит полное обновление, даже если это был (с точки зрения пользователя) всего лишь патч. Конечно, это работает только в том случае, если установщик исправлений на самом деле совпадает с полным установщиком.

4. Ваша реальная проблема заключается в том, что вы переименовываете каталог. Это неправильно. Это все ломает. Если вы переименуете каталог установки, пользователь не сможет удалить приложение, так как комментарий к удалению в реестре не будет указывать на допустимое местоположение. Вся эта идея с версией в имени каталога неверна. Хотя это все еще выполнимо. Но вы должны использовать другой подход. Не переименовывайте каталог. Вместо этого просто удалите предыдущую версию при установке новой. Для этого здесь существует множество существующих вопросов (в конце концов, это то, что вы UnInstallOldVersion делаете).

5. @PMF Это хорошая идея. Однако полная установка составляет около 300 МБ , а патч-всего около 10 МБ. Таким образом, основная часть файлов не входит в комплект установщика исправлений. Я обновлю свой пост этой информацией