ultra setup org jrsoftware isdl inno for downloads docs installer inno-setup

installer - org - inno setup version 5.5 9



Inno Setup: ¿Cómo desinstalar automáticamente la versión instalada anterior? (11)

Al usar Inno Setup, no hay razón para desinstalar una versión anterior a menos que esa versión haya sido instalada por un programa de instalación diferente. De lo contrario, las actualizaciones se manejan automáticamente.

Estoy usando Inno Setup para crear un instalador.

Quiero que el instalador desinstale automáticamente la versión instalada anterior, en lugar de sobrescribirla. ¿Cómo puedo hacer eso?


Debo estar perdiendo algo. Los nuevos archivos se copian en el directorio de destino antes de que se realice la eliminación de la instalación anterior. Luego viene el desinstalador que los elimina y elimina el directorio.


He usado lo siguiente. No estoy seguro de que sea la forma más sencilla de hacerlo, pero funciona.

Esto usa {#emit SetupSetting("AppId")} que se basa en el preprocesador Inno Setup. Si no usa eso, corte y pegue su ID de aplicación directamente.

///////////////////////////////////////////////////////////////////// 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;

Alternativas

Consulte también esta publicación en el blog "Inno Setup Script Sample for Version Comparison", que va un paso más allá, y lee el número de versión de cualquier versión previamente instalada, y compara ese número de versión con el del paquete de instalación actual.


La respuesta proporcionada por Craig McQueen es totalmente viable. Aunque, agregaría esos comentarios:

  • El {#emit SetupSetting("AppId")} no funciona para mí, así que solo agrego mi ID de aplicación.
  • No quería ejecutar mi programa de desinstalación, porque tengo un archivo de configuración INI almacenado en la carpeta AppData / que el desinstalador elimina y no quiero que se borre cuando instale una nueva versión. Entonces, modifiqué un poco el código proporcionado por Craig McQueen para eliminar el directorio donde está instalado el programa, luego de recuperar su ruta.

Entonces, con respecto al código de Craig McQueen, los cambios son:

  • Recupere la clave InstallLocation en lugar de la clave UninstallString .
  • Utilice la función DelTree lugar de Exec(sUnInstallString, ...)

Me edité el código @Crain Mc-Queen, creo que este código es mejor porque no es necesario modificarlo en un proyecto diferente:

[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;


No use la sección [Ejecutar], sino la [Desinstalar Ejecución]. De hecho, el programa en [Ejecutar] se ejecuta después de la instalación, lo que provoca la desinstalación de su programa inmediatamente después de la instalación: - | En cambio, la sección [UninstallRun] se evalúa antes de la instalación.


Para cualquiera que use GetUninstallString() sugerido anteriormente para forzar una desinstalación dentro de CurStepChanged() y tenga problemas de almacenamiento en caché de disco, vea a continuación una solución relacionada que realmente espera un tiempo después de la desinstalación para que se desinstale el exe de desinstalación.

¿Problema de almacenamiento en caché de disco con inno-setup?


Puede ejecutar un desinstalador en la sección [código]. Debe averiguar cómo obtener la ruta al desinstalador existente. Para simplificar, cuando instalo mis aplicaciones agrego un valor de cadena de registro que apunta a la carpeta que contiene el desinstalador, y ejecuto el desinstalador en la devolución de llamada de InitializeWizard.

Tenga en cuenta que los nombres de los desinstaladores de instalación de Inno son todos de la forma uninsnnn.exe, debe tener esto en cuenta en su código.


Si "solo quieres eliminar los iconos antiguos" (porque los tuyos han cambiado / actualizado) puedes usar esto:

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

Esto se ejecuta "al comienzo de la instalación", por lo que básicamente elimina los íconos antiguos, y los nuevos seguirán instalados allí una vez que se haya completado.

Simplemente hago esto con cada instalación "en caso de que algo haya cambiado" en cuanto a los iconos (todo se vuelve a instalar de todos modos).



Debería poder leer la cadena de desinstalación del registro, dado el AppId (es decir, el valor que utilizó para el AppID en la sección [Setup] ). Se puede encontrar en Software/Microsoft/Windows/CurrentVersion/Uninstall/{AppId}/ (podría ser HKLM o HKCU , así que mejor compruebe ambos) donde {AppId} debería sustituirse por el valor real que utilizó. Busque los valores UninstallString o QuietUninstallString y utilice la función Exec para ejecutarlo desde su función de evento InitializeSetup() .

Actualización: solución alternativa no operativa eliminada utilizando una entrada de la sección [Run] con {uninstallexe} - ¡gracias a todos los comentaristas que lo señalaron!