views:

1602

answers:

6

I'm using InnoSetup to create installer. I want the installer to automatically uninstall the previous installed version, instead of overwriting it. How can I do that?

A: 

This is rather an advanced topic (I think).

I would suggest asking this question in the news group of innosetup:

news://news.jrsoftware.org/jrsoftware.innosetup

Please, if you receive an answer in the news group, post the result here.

Edelcom
+2  A: 

Haven't tried it yet myself, but I guess this just might work, assuming that you kept the AppId from the previous installation:

[Run]
Filename: {uninstallexe}; Parameters: /VERYSILENT; StatusMsg: Uninstalling previous version; Flags: skipifdoesntexist

If this doesn't work, you should be able to read the uninstall string from the registry, given the AppId (i.e. the value you used for AppID in the [Setup]-section). It could be found under Software\Microsoft\Windows\CurrentVersion\Uninstall\{AppId}\ (could be either HKLM or HKCU, so best check both) where {AppId} should be substituted with the actual value you used. Look for the UninstallString or QuietUninstallString values and use the Exec function to run it from your InitializeSetup() event function.

Oliver Giesen
+1, but definitely use scripting to read the old uninstaller name, because otherwise it won't work if a different path has been entered by the user.
mghie
I don't think the `[Run]` section solution will work, because it runs too late in the installation process. From Inno Setup manual: *The [Run] section is optional, and specifies any number of programs to execute after the program has been successfully installed, but before the Setup program displays the final dialog.*
Craig McQueen
+6  A: 

I have used the following. I'm not sure it's the simplest way to do it but it works.

This uses {#emit SetupSetting("AppId")} which relies on the Inno Setup Preprocessor. If you don't use that, cut-and-paste your App ID in directly.

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

Alternatives

See also this blog post "Inno Setup Script Sample for Version Comparison" which goes one step further, and reads the version number of any previously installed version, and compares that version number with that of the current installation package.

Craig McQueen
Tested and confirmed to work. Using it in my solution.
soupagain
A: 

Using scripts is too complex. I'm using Actual Installer. See the option 'Installation-Upgrade' - 'Uninstall old version before installation'.

Markus
InnoSetup is free. That's the matter :)
Vimvq1987
A: 

When using Inno Setup, there's no reason to uninstall a previous version unless that version was installed by a different installer program. Otherwise upgrades are handled automatically.

mlaan
Our program got a change in structure, so old version need to be uninstalled.
Vimvq1987
No it doesnt, you can add entries to your script to handle the structure change during an update.
mlaan
A: 

@mlaan: We have the same issue. Our structure was changed and some update external libraries were added with different file names: gdal16.dll became gdal17.dll I was also thinking of uninstaller the older version first, but you say it is not necessary. Can you explain how to use your option?

Paul Meems