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?
installation
inno-setup
Quan Mai
fuente
fuente
Respuestas:
Debería poder leer la cadena de desinstalación del registro, dado el AppId (es decir, el valor que utilizó
AppID
en la[Setup]
sección-). Se puede encontrar enSoftware\Microsoft\Windows\CurrentVersion\Uninstall\{AppId}\
(podría serHKLM
oHKCU
, por lo que es mejor marcar ambos) donde{AppId}
debe sustituirse por el valor real que utilizó. Busque los valoresUninstallString
oQuietUninstallString
y use laExec
función para ejecutarlo desde suInitializeSetup()
función de evento.Actualización: se eliminó la solución alternativa que no funciona usando una
[Run]
entrada de sección con{uninstallexe}
- ¡gracias a todos los comentaristas que señalaron esto!fuente
[Run]
solución de la sección funcione, porque se ejecuta demasiado tarde en el proceso de instalación. Del manual Inno Setup: La sección [Ejecutar] es opcional y especifica cualquier número de programas para ejecutar después de que el programa se haya instalado correctamente, pero antes de que el programa de instalación muestre el cuadro de diálogo final.He usado lo siguiente. No estoy seguro de que sea la forma más sencilla de hacerlo, pero funciona.
Este utiliza
{#emit SetupSetting("AppId")}
que se basa en el preprocesador de configuración Inno. Si no lo usa, corte y pegue su ID de aplicación directamente.[Code] { ///////////////////////////////////////////////////////////////////// } 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 de blog "Ejemplo de secuencia de comandos de configuración de Inno para la comparación de versiones", que va un paso más allá, lee el número de versión de cualquier versión instalada previamente y compara ese número de versión con el del paquete de instalación actual.
fuente
... UserSIDs: TArrayOfString; I: Integer; ... if not RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString) then if isAdminLoggedOn() and RegGetSubkeyNames( HKEY_USERS, '', UserSIDs ) then for I := 0 to GetArrayLength( UserSIDs ) - 1 do begin if RegQueryStringValue( HKEY_USERS, UserSIDs[I] + '\' + sUnInstPath, 'UninstallString', sUnInstallString ) then break; end;
Si "solo desea eliminar los íconos antiguos" (porque los suyos han cambiado / actualizado), puede usar esto:
Esto se ejecuta "al comienzo de la instalación", por lo que básicamente elimina los iconos antiguos, y los nuevos seguirán instalados allí después de que esto esté completamente hecho.
Solo hago esto con cada instalación "en caso de que algo haya cambiado" en cuanto a iconos (todo se reinstala de todos modos).
fuente
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 gestionan automáticamente.
fuente
[InstallDelete]
sección para eliminar archivos / directorios antiguos. Los nuevos archivos se colocarán en las ubicaciones correctas durante la instalación.La respuesta proporcionada por Craig McQueen es totalmente viable. Aunque, agregaría esos comentarios:
{#emit SetupSetting("AppId")}
código no me funciona, así que solo agrego mi ID de aplicación.Entonces, con respecto al código de Craig McQueen, los cambios son:
InstallLocation
llave en lugar de laUninstallString
llave.DelTree
función en lugar de laExec(sUnInstallString, ...)
fuente
Para cualquier persona que use lo
GetUninstallString()
sugerido anteriormente para forzar una desinstalación internaCurStepChanged()
y tenga problemas de almacenamiento en caché de disco, consulte a continuación una solución relacionada que en realidad espera un tiempo después de la desinstalación para que se elimine el desinstalador exe.¿Problema de almacenamiento en caché de disco con inno-setup?
fuente
Puede ejecutar un desinstalador en la sección [código]. Tienes que 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 simplemente ejecuto el desinstalador en la devolución de llamada de InitializeWizard.
Tenga en cuenta que los nombres del desinstalador de instalación de Inno tienen el formato uninsnnn.exe, debe tenerlo en cuenta en su código.
fuente
Me editaron el código de @Crain Mc-Queen, creo que este código es mejor porque no es necesario modificarlo en un proyecto diferente:
fuente
Debo estar perdiendo algo. Los nuevos archivos se copian en el directorio de destino antes de que se elimine la instalación anterior. Luego viene el desinstalador los borra y elimina el directorio.
fuente
No utilice la sección [Ejecutar], sino [UninstallRun]. De hecho, el programa en [Ejecutar] se ejecuta después de la instalación, lo que provoca la desinstalación del programa inmediatamente después de la instalación: - | En su lugar, la sección [UninstallRun] se evalúa antes de la instalación.
fuente
[UninstallRun]
no es una solución para la pregunta.Siga este enlace: http://news.jrsoftware.org/news/innosetup/msg55323.html
En la función InitializeSetup (), puede llamar a "MSIEXEC / x {su ID de programa}" después de que el usuario le pida que desinstale la versión anterior.
fuente