Search this site (www.microchipC.com).





CCS C Compiler for Microchip PIC micros

Your ad here

 

Using Inno Setup to Create a Versioned Installer

An important piece of any Windows suppport application is an installer that is easy to use.

For Windows distributions, www.MicrochipC.com uses Inno Setup to generate custom setup executables. Inno Setup is superior to InstallShield in almost every way, its lightweight, simple, and easy to use.

One feature that Inno Setup v5 lacks is auto-versioning support. Also referred to as auto-update or auto-upgrade, this is the ability for the application to handle upgrades seamlessly, or warn the user if they are downgrading the program.

MicrochipC has released InnoSetupAV, a sample installer script and set of instructions to add seamless auto-versioning and upgrading support to existing InnoSetup scripts.

Advantages

  • Handles all version updates seamlessly.
  • Auto-detects if a previous version has already been installed, regardless of which directory the user originaly chose, and automatically updates the older version.
  • During an update, skips relevant pages for simplification.
  • Warns the user if an older verison is being installed over the top of a newer version.
  • Automatically generates a different installer filename if the version is incremented.
  • Demonstrates use of #defines to simplify updates.

Requirements

  • Windows (any version).
  • Inno Setup v5.x.
  • Inno Setup Preprocessor.

Setup

Install Inno Setup v5 or above.

Install the Inno Setup Preprocessor. This allows Inno Setup to handle #defines, and is essential for clean, maintainable scripts.

Step-by-step instrucitons

To insert the version into the Inno Setup script, add these lines:

; version
; 1. For the versioning to work correctly, vbuild must constantly increase for every release.
; 2. vbuild starts out at 1000 and will increment every build for the life of the program.
; 3. For example, it would go v1.5.1001, then v1.6.1002, then v1.7.1004, etc.
; 4. This behaviour can be altered to suit other versioning schemes by changing the functions below.
#define vmajor 1
#define vminor 1
#define vbuild 2350

Define the application name:

#define appname "MicrochipC PSU Utility"

Now that we have the version defined, we can auto-generate the filename:

OutputBaseFilename={#appname} v{#vmajor}.{#vminor}.{#vbuild}

Now, we need to add a key to the registry to keep track of the currently installed version:

[Registry]
; ---start autoupdate code; see http://agiletrack.net/samples/sample-istool-installer.html--
Root: HKLM; Subkey: Software\{#appname}; ValueType: string; ValueName: CurrentVersion; ValueData: {code:GetAppCurrentVersion|''}; Flags: uninsdeletekey
; ---end autoupdate code---

Dont worry about the function call in this line; this will be added later.

Now, add funcitons to handle the versioning:

; ---start autoupdate code; see http://agiletrack.net/samples/sample-istool-installer.html--
[Code]
function GetAppMajorVersion(param: String): String;
begin
Result:='{#vmajor}';
end;

function GetAppMinorVersion(param: String): String;
begin
Result:='{#vminor}';
end;

function GetAppCurrentVersion(param: String): String;
begin
Result:='{#vbuild}';
end;

function GetAppID(param: String): String;
begin
Result := '{#appname}';
end;

function GetPathInstalled(AppID: String): String;
var
PrevPath: String;
begin
PrevPath := '';
if not RegQueryStringValue(HKLM, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\'+AppID+'_is1', 'Inno Setup: App Path', PrevPath) then begin
RegQueryStringValue(HKCU, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\'+AppID+'_is1', 'Inno Setup: App Path', PrevPath);
end;
Result := PrevPath;
end;

function GetInstalledVersion(): String;
var
InstalledVersion: String;
begin
InstalledVersion := '';
RegQueryStringValue(HKLM, 'Software\{#appname}', 'Version', InstalledVersion);
Result := InstalledVersion;
end;

function GetInstalledCurrentVersion(): String;
var
InstalledCurrentVersion: String;
begin
InstalledCurrentVersion := '';
RegQueryStringValue(HKLM, 'Software\{#appname}', 'CurrentVersion', InstalledCurrentVersion);
Result := InstalledCurrentVersion;
end;

function InitializeSetup(): Boolean;
var
Response: Integer;
PrevDir: String;
InstalledVersion: String;
InstalledCurrentVersion: String;
//VersionError: String;
begin
Result := true;

// read the installation folder
PrevDir := GetPathInstalled(getAppID(''));

if length(Prevdir) > 0 then begin
// I found the folder so it's an upgrade.

// compare versions
InstalledCurrentVersion := GetInstalledCurrentVersion();
InstalledVersion := GetAppCurrentVersion('');
if (InstalledCurrentVersion < InstalledVersion) then begin
Result := True;
end else if (InstalledCurrentVersion = InstalledVersion) then begin
Response := MsgBox(
'It appears that the existing {#appname} installation is already current.' + #13#13 +
'Do you want to continue with the update installation?', mbError, MB_YESNO
);
Result := (Response = IDYES);
end else begin
Response := MsgBox(
'It appears that the existing {#appname} installation is newer than this update.' + #13#13 +
'The existing installation is v'+ GetAppMajorVersion('') + '.' + GetAppMinorVersion('')+'.'+InstalledCurrentVersion +'. This update will change the installation to v'+ GetAppMajorVersion('') + '.' + GetAppMinorVersion('')+'.'+ GetAppCurrentVersion('') + '.' + #13#13 +
'Do you want to continue with the update installation?', mbError, MB_YESNO
);
Result := (Response = IDYES);
end;
end else begin
// Didn't find the folder so its a fresh installation.
Result:=true;
end;
end;

function ShouldSkipPage(PageID: Integer): Boolean;
var
PrevDir:String;
begin
PrevDir := GetPathInstalled(getAppID(''));
if length(Prevdir) > 0 then begin
// skip selectdir if It's an upgrade
if (PageID = wpSelectDir) then begin
Result := true;
end else if (PageID = wpSelectProgramGroup) then begin
Result := true;
end else if (PageID = wpSelectTasks) then begin
Result := true;
end else begin
Result := false;
end;
end;
end;

Download

Download InnoSetupAV v1.00.

Tests

Try the following tests to see if the script is working as designed.

  • Try changing vbuild. When you recompile, the generated executable will have a different name.
  • The first time you install, try installing to a non-standard directory, ie: "E:\test". When you run the setup again, it will automatically default to install the next version in "E:\test". If you want to change the location of where the program is installed, simply run the uninstallation program then reinstall it again.
  • Try incrementing vbuild, then running the setup again. Notice that the setup will default to the previously selected directory.
  • Try decrementing vbuilt, then running the setup again. Notice that it warns you that you are downgrading the setup.
  • Try leaving vbuild the same, then running setup. Notice that it warns you that you that the versions are the same.
  • Note the versioning rules built into this script:
    • For the versioning to work correctly, vbuild must constantly increase for every release.
    • vbuild starts out at a number (ie: 1000) and will increment every build for the life of the program.
    • For example, it would go v1.5.1001, then v1.6.1002, then v1.7.1004, etc.
    • This behaviour can be altered to suit other versioning schemes by changing the functions below.

Comments

Send questions or comments to my email address.

This applicaiton is free - enjoy!



This site is non-profit. Ad revenue almost covers hosting costs.

We welcome any suggesions or comments! Send them to Shane Tolmie on support@microchipc.com. This site is a completely separate site to www.microchip.com, and is maintained independently of Microchip Ltd., manufacturers of the PIC micro. All code on this site is free for non-commercial use, unless stated otherwise. Commercial use normally free, however, it is prohibited without contacting support@microchipc.com for permission. All content on this site created by Shane Tolmie is copyrighted by Shane Tolmie 1999-2009. Click to advertise on this website - $29.90 for a banner ad which will reach 55,000 user sessions per month. One months free trial!