We prepare installers using Inno Setup. So a user installs the software. When new version is released, a new installer updates the software. So far so good.
But some people want to have both old version of the software and new one.
Is it possible to make an installer ask if a user wants to update current installation or install new version side by side.
In InitializeSetup
event function, detect if the application is installed already. If it is, ask user, and if he/she chooses to install a new copy, change AppId
and DefaultDirName
to version-specific values to force a new installation.
[Setup]
#define AppId "My Program"
#define SetupReg \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\" + AppId + "_is1"
#define DispVerReg "DisplayVersion"
#define ApplicationVersion() \
ParseVersion('MyProg.exe', Local[0], Local[1], Local[2], Local[3]), \
Str(Local[0]) + "." + Str(Local[1])
[Setup]
AppId={code:GetAppId}
AppName=My Program
AppVersion={#ApplicationVersion}
DefaultDirName={code:GetDefaultDirName}
UsePreviousLanguage=no
[Files]
Source: "MyProg.exe"; DestDir: "{app}"
[Code]
var
AppId: string;
DefaultDirName: string;
function GetAppId(Param: string): string;
begin
Result := AppId;
Log('AppId = ' + Result);
end;
function GetDefaultDirName(Param: string): string;
begin
Result := DefaultDirName;
Log('DefaultDirName = ' + Result);
end;
function InitializeSetup(): Boolean;
var
PrevVersion: string;
CurVersion: string;
Msg: string;
R: Integer;
begin
CurVersion := '{#ApplicationVersion}';
Log(Format('Installing "%s"', [CurVersion]));
Result := True;
AppId := '{#AppId}';
DefaultDirName := ExpandConstant('{pf}\My Program');
if RegQueryStringValue(HKLM, '{#SetupReg}', '{#DispVerReg}', PrevVersion) or
RegQueryStringValue(HKCU, '{#SetupReg}', '{#DispVerReg}', PrevVersion) then
begin
Msg :=
Format(
'Version is %s already installed. Do you want to upgrade to %s?'#13#10 +
#13#10 +
'Press Yes, to replace %0:s with %1:s.'#13#10 +
'Press No, to keep %0:s and add separate installation of %1:s.'#13#10, [
PrevVersion, CurVersion]);
R := MsgBox(Msg, mbConfirmation, MB_YESNOCANCEL);
if R = IDYES then
begin
Log('User chose to replace previous installation');
end
else
if R = IDNO then
begin
AppId := AppId + CurVersion;
DefaultDirName := DefaultDirName + ' ' + CurVersion;
Log('User chose to install new copy - using ID ' + AppId);
end
else
begin
Log('User chose to cancel installation');
Result := False;
end;
end;
end;
And of course, this is installation part only. Your application must be able to somehow separate configurations for the separate installation instances.