Category Archives: Installers

Innosetup and Appmethod

RiverSoftAVG.com uses Innosetup to create the installers for all of its products.  With the recent release of Appmethod, I wanted the installers to detect if it was RAD Studio or Appmethod installed on a user’s computer.  This way, I could make one installer for all versions of RAD Studio and Appmethod, but “personalize” it based on what was detected.  I don’t know how others are doing it but here is how I did it.

First, I inspected the registry after installing appmethod and realized that Embarcadero sets the ‘(Default)’ value of the ‘SOFTWARE\Embarcadero\BDS\xx.0\Personalities’ (where xx is the version number), under the HKEY_CURRENT_USER, to the installed product.  For example, ‘SOFTWARE\Embarcadero\BDS\12.0\Personalities’ contains ‘RAD Studio XE5’ ‘SOFTWARE\Embarcadero\BDS\14.0\Personalities’ contains ‘RAD Studio XE6’.  For Appmethod, ‘SOFTWARE\Embarcadero\BDS\14.0\Personalities’ contains ‘Appmethod’.  Now, Appmethod and RAD Studio XE6 cannot coexist on the same computer so all I need to do was look for ‘Appmethod’ or ‘RAD Studio XE6’ for that value.  I created a function in Innosetup called IsAppmethodInstalled to do that:

function IsAppmethodInstalled( SVers: String ): Boolean;
var
  Vers: Integer;
  i: Integer;
  DefApp: String;
begin
  // check if Delphi is installed
  // 50 = Delphi5, 60 = Delphi 6 etc,
  // can check for ANY of multiple versions of delphi if separated by spaces
  i := Pos(' ', SVers);
  if i > 0 then
  begin
    result := IsAppmethodInstalled( Copy(SVers, i + 1, Length(SVers)) );
    if result then Exit;
    SVers := Copy(SVers, 1, i-1);
  end;
  Vers := StrToInt(SVers);
  case Vers of
    200: result := RegQueryStringValue( HKCU, 'SOFTWARE\Embarcadero\BDS\14.0\Personalities', '', DefApp ); // XE6/Appmethod 1.14
  else
    result := False;
  end;
  if result then
  begin
    result := DefApp = 'Appmethod';
  end;
end;

The SVers parameter contains the version string which tells the function which product to look for (though for now, there is only the one).  Basically, the function looks in the registry for the ‘(Default)’ value (which is a blank string), pulls it out if it exists, and then sees if it equals ‘Appmethod’. To use the function, I call the function as part of the check parameter when I am defining the setup [Components] in innosetup (note that I also have a similar IsDelphiInstalled function that just checks for the RegKeyExists for each version of Delphi, e.g., 200: result := RegKeyExists( HKCU, ‘SOFTWARE\Embarcadero\BDS\14.0’ );):

<strong>[Components]</strong>
Name: main; Description: Main Files; Types: full compact custom; Flags: fixed
Name: help; Description: Help Files; Types: full
Name: d14; Description: Delphi 2010/Rad Studio 2010 (Win32) Library Files; Types: full; check: IsDelphiInstalled('140');
Name: d15; Description: Delphi XE/Rad Studio XE (Win32) Library Files; Types: full; check: IsDelphiInstalled('150');
Name: d16; Description: Delphi XE2/Rad Studio XE2 (Win32/FMX) Library Files; Types: full; check: IsDelphiInstalled('160');
Name: d16x64; Description: Delphi XE2/Rad Studio XE2 (Win64) Library Files; Types: full; check: IsDelphiInstalled('160');
Name: d17; Description: Delphi XE3/Rad Studio XE3 (Win32/FMX) Library Files; Types: full; check: IsDelphiInstalled('170');
Name: d17x64; Description: Delphi XE3/Rad Studio XE3 (Win64) Library Files; Types: full; check: IsDelphiInstalled('170');
Name: d18; Description: Delphi XE4/Rad Studio XE4 (Win32/FMX) Library Files; Types: full; check: IsDelphiInstalled('180');
Name: d18x64; Description: Delphi XE4/Rad Studio XE4 (Win64) Library Files; Types: full; check: IsDelphiInstalled('180');
Name: d19; Description: Delphi XE5/Rad Studio XE5 (Win32/FMX) Library Files; Types: full; check: IsDelphiInstalled('190');
Name: d19x64; Description: Delphi XE5/Rad Studio XE5 (Win64) Library Files; Types: full; check: IsDelphiInstalled('190');
Name: AM20; Description: Appmethod Library Files; Types: full; check: IsAppmethodInstalled('200');
Name: d20; Description: Delphi XE6/Rad Studio XE6 (Win32/FMX) Library Files; Types: full; check: IsDelphiInstalled('200') and not IsAppmethodInstalled('200');
Name: d20x64; Description: Delphi XE6/Rad Studio XE6 (Win64) Library Files; Types: full; check: IsDelphiInstalled('200') and not IsAppmethodInstalled('200');

After that, I can use the Components parameter ‘AM20’ to control what I install on the user’s computer.  That’s it.

Hopefully this will help other component developers who use Innosetup.  Take care for now and Happy CodeSmithing!