Cuando uno se dedica al desarrollo de software es muy común la búsqueda de una herramienta que permita crear instaladores. Para el caso de distribuir software en windows yo he optado por el uso de Inno Setup, es una herramienta gratuita y muy fácil de usar.
Uno de los incomvenientes que he tenido es cuando se van creando diferentes versiones de un software, lo cual genera diferentes instaladores, el software puede cambiar de estructura y es combeniente la desinstalación de la versión anterior antes de continuar con la nueva. En este pequeño mini tutorial veremos cómo hacer que nuestro script Inno Setup desinstale una versión anterior de un software antes de continuar con la instalación.
Los instaladores creados con Inno Setup crean una clave e el registro de windows que contiene la información del software instalado, entre esta información se encuentra el ejecutable para la desinstalación:
HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\{APP_ID}_is1
{APP_ID} debe ser reemplazado por el App ID designado por Inno Setup, dentro de esta clave del registro de windows se encuentra el String UninstallString, el cual contiene la ruta al desinstalador de nuestra versión anterior:
Lo primero que debemos hacer es crear una función en la sección [Code] de nuestro script de instalación, el código sería el siguiente:
function GetEjecutableDesinstalacion(): String; var m_Key: String; m_executable: String; begin m_Key := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1'); m_executable := ''; if not RegQueryStringValue(HKLM, m_Key, 'UninstallString', m_executable) then RegQueryStringValue(HKCU, m_Key, 'UninstallString', m_executable); Result := RemoveQuotes(m_executable); end;
La sentencia {#emit SetupSetting("AppId")}_is1 obtiene de manera automática el AppId especificado en el script Inno Setup dónde se coloque el código. Ahora debemos crear una función que me permita realizar la desinstalación, simplemente llamará a la función anterior para obtener la ruta del instalador y lo ejecutará:
procedure Desinstalar(); var m_sald: String; m_exitCode: Integer; begin m_sald:= GetEjecutableDesinstalacion(); if m_sald <> '' then begin if Exec(m_sald, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, m_exitCode) then end else end;
Listo, ahora solo es necesario llamar al procedimiento Desinstalar() antes de que se ejecute la instalación, para esto podemos usar el evento CurStepChanged(CurStep: TSetupStep), el cuál nos permitirá llamar a nuestro procedimiento cuando llegue a la fase de instalación:
procedure CurStepChanged(CurStep: TSetupStep); begin if (CurStep=ssInstall) then begin Desinstalar(); end; end;
Listo, con esto se realizará la desinstalación automática de una versión de nuestro software antes de continuar con la instalación, recuerda que estas funciones deben estar en la sección [Code] de tu script de instalación, aqui puedes ver el código completo:
[Code] function GetEjecutableDesinstalacion(): String; var m_Key: String; m_executable: String; begin m_Key := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1'); m_executable := ''; if not RegQueryStringValue(HKLM, m_Key, 'UninstallString', m_executable) then RegQueryStringValue(HKCU, m_Key, 'UninstallString', m_executable); Result := RemoveQuotes(m_executable); end; procedure Desinstalar(); var m_sald: String; m_exitCode: Integer; begin m_sald:= GetEjecutableDesinstalacion(); if m_sald <> '' then begin if Exec(m_sald, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, m_exitCode) then end else end; procedure CurStepChanged(CurStep: TSetupStep); begin if (CurStep=ssInstall) then begin Desinstalar(); end; end;