Inno Setup: как автоматически удалить предыдущую установленную версию?

Я использую Inno Setup для создания установщика.

Я хочу, чтобы установщик автоматически удалял предыдущую установленную версию, а не перезаписывал ее. Как я могу это сделать?

Вы должны иметь возможность прочитать строку удаления из реестра, учитывая AppId (то есть значение, которое вы использовали для AppID в разделе [Setup] ). Его можно найти в разделе « Software\Microsoft\Windows\CurrentVersion\Uninstall\{AppId}\ (может быть либо HKLM либо HKCU , так что лучше проверить оба), где {AppId} следует заменить фактическим значением, которое вы использовали. Найдите значения UninstallString или QuietUninstallString и используйте функцию Exec для ее запуска из функции события InitializeSetup() .

Обновление: удалено нерабочее альтернативное решение, используя запись [Run] -секция с {uninstallexe} – благодаря всем комментаторам, которые указали это!

Я использовал следующее. Я не уверен, что это самый простой способ сделать это, но он работает.

Это использует {#emit SetupSetting("AppId")} который опирается на препроцессор Inno Setup. Если вы не используете это, вы можете напрямую вставить свой идентификатор приложения.

 ///////////////////////////////////////////////////////////////////// function GetUninstallString(): String; var sUnInstPath: String; sUnInstallString: String; begin sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#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() <> ''); 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 <> '' 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; 

альтернативы

См. Также это сообщение в блоге «Пример сценария установки Inno Setup для сравнения версий», который идет на один шаг дальше и читает номер версии любой ранее установленной версии и сравнивает номер версии с номером текущего установочного пакета.

При использовании Inno Setup нет причин для удаления предыдущей версии, если эта версия не была установлена ​​другой программой-установщиком. В противном случае обновление выполняется автоматически.

Если вы просто хотите удалить старые значки (потому что вы изменили / обновили), вы можете использовать это:

 ; attempt to remove previous versions' icons [InstallDelete] Type: filesandordirs; Name: {group}\*; 

Это запускается «в начале установки», поэтому в основном удаляет старые значки, и ваши новые будут по-прежнему установлены после завершения этого.

Я просто делаю это при каждой установке «на случай, если что-то изменилось» значок мудрый (все равно все переустанавливается).

Ответ, предоставленный Крейгом МакКуином, полностью жизнеспособен. Хотя, я бы добавил эти комментарии:

  • Код {#emit SetupSetting("AppId")} не работает для меня, поэтому я просто добавляю свой идентификатор приложения.
  • Я не хотел запускать мою программу удаления, потому что у меня есть файл конфигурации INI, который хранится в папке AppData /, которую удаляет деинсталлятор, и я не хочу, чтобы он был удален при установке новой версии. Итак, я немного изменил код, предоставленный Крейгом МакКуином, чтобы удалить каталог, в котором установлена ​​программа, после получения его пути.

Итак, в отношении кода Крейга МакКуина изменения:

  • InstallLocation ключ InstallLocation вместо ключа UninstallString .
  • Используйте функцию DelTree вместо Exec(sUnInstallString, ...)

я получил отредактированный код @Crain Mc-Queen, я думаю, что этот код лучше, потому что не нужно модифицировать в другом проекте:

 [Code] function GetNumber(var temp: String): Integer; var part: String; pos1: Integer; begin if Length(temp) = 0 then begin Result := -1; Exit; end; pos1 := Pos('.', temp); if (pos1 = 0) then begin Result := StrToInt(temp); temp := ''; end else begin part := Copy(temp, 1, pos1 - 1); temp := Copy(temp, pos1 + 1, Length(temp)); Result := StrToInt(part); end; end; function CompareInner(var temp1, temp2: String): Integer; var num1, num2: Integer; begin num1 := GetNumber(temp1); num2 := GetNumber(temp2); if (num1 = -1) or (num2 = -1) then begin Result := 0; Exit; end; if (num1 > num2) then begin Result := 1; end else if (num1 < num2) then begin Result := -1; end else begin Result := CompareInner(temp1, temp2); end; end; function CompareVersion(str1, str2: String): Integer; var temp1, temp2: String; begin temp1 := str1; temp2 := str2; Result := CompareInner(temp1, temp2); end; function InitializeSetup(): Boolean; var oldVersion: String; uninstaller: String; ErrorCode: Integer; vCurID :String; vCurAppName :String; begin vCurID:= '{#SetupSetting("AppId")}'; vCurAppName:= '{#SetupSetting("AppName")}'; //remove first "{" of ID vCurID:= Copy(vCurID, 2, Length(vCurID) - 1); // if RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + vCurID + '_is1') then begin RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + vCurID + '_is1', 'DisplayVersion', oldVersion); if (CompareVersion(oldVersion, '{#SetupSetting("AppVersion")}') < 0) then begin if MsgBox('Version ' + oldVersion + ' of ' + vCurAppName + ' is already installed. Continue to use this old version?', mbConfirmation, MB_YESNO) = IDYES then begin Result := False; end else begin RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + vCurID + '_is1', 'UninstallString', uninstaller); ShellExec('runas', uninstaller, '/SILENT', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode); Result := True; end; end else begin MsgBox('Version ' + oldVersion + ' of ' + vCurAppName + ' is already installed. This installer will exit.', mbInformation, MB_OK); Result := False; end; end else begin Result := True; end; end; 

Вы можете выполнить деинсталляцию в разделе [code]. Вы должны выяснить, как получить путь к существующему деинсталлятору. Для простоты, когда я устанавливаю свои приложения, я добавляю значение строки реестра, указывающее на папку, содержащую деинсталлятор, и просто выполняем деинсталлятор в обратном вызове InitializeWizard.

Имейте в виду, что имена деинсталляторов установки Inno имеют форму uninsnnn.exe, вам нужно учитывать это в своем коде.

Для тех, кто использует предложенную выше GetUninstallString() чтобы принудительно удалить внутри CurStepChanged() и проблемы с кэшированием диска, см. Ниже соответствующее решение, которое на самом деле ждет некоторое время после unistallation для удаления exe-файла exe!

Проблема с кэшированием диска с помощью inno-setup?

Я должен что-то упустить. Новые файлы копируются в целевой каталог до удаления старой установки. Затем появляется деинсталлятор, который удаляет их и удаляет каталог.

Не используйте раздел [Выполнить], но [UninstallRun]. Infact, программа под [Run] выполняется после установки, что приводит к удалению вашей программы сразу после установки: – | Вместо этого раздел [UninstallRun] оценивается перед установкой.

Следуйте по этой ссылке: http://news.jrsoftware.org/news/innosetup/msg55323.html

В функции InitializeSetup () вы можете вызвать «MSIEXEC / x {ваш идентификатор программы]» после запроса пользователя для удаления старой старой версии

Interesting Posts

«& S » указывает на непрерывные символы в строке std ::?

Как отлаживать проекты библиотеки внешних classов в visual studio?

Facebook Graph API v2.0 + – / me / friends возвращает пустое место или только друзья, которые также используют мое приложение

CMake: Как настроить зависимости источника, библиотеки и CMakeLists.txt?

3,5 мм разъем для наушников -> компонентное видео?

Как включить фронтальную вспышку программно в Android?

Использование «системы» perl

Угловой 2.0. Разница @View @Component

Почему плохо иметь две антивирусные системы?

где лучшее место для сохранения изображений с пользователей

Android KitKat 4.4 Hangouts не может обрабатывать намерение отправки SMS

Разбор строк в Java с вкладкой «\ t» разделителя с использованием split

Как я могу сделать графики согласованной ширины в ggplot (с легендами)?

Установка уровня сжатия jpg с помощью ImageIO в Java

Как я могу набрать испанский инвертированный знак вопроса в Emacs?

Давайте будем гением компьютера.