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 claveUninstallString
. - Utilice la función
DelTree
lugar deExec(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).
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 solicite desinstalar la versión vieja anterior
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!