#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.0 (ОК)
- Создается каталог
App Name 1.1.0
- Создается каталог
- Пользователь устанавливает патч — 1.1.1 (ОК)
UsePreviousAppDir=true
поэтому он пишет поверх каталогаApp Name 1.1.0
App Name 1.1.0
переименован вApp Name 1.1.1
как частьCurStepChanged()
whenCurStep
isssPostInstall
.
- Пользователь устанавливает полное приложение — 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
.
- Если значение UsePreviousAppDir равно true, каталог
Как я могу настроить свой файл 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 МБ. Таким образом, основная часть файлов не входит в комплект установщика исправлений. Я обновлю свой пост этой информацией