24

I am trying to configure Inno setup for my software (this is a C# software). I plan to release many versions of my software, I would like to change the Inno setup installer interface if an older version of my application is already installed on the computer. In this case, the user shouldn't be able to change the install directory.

There are four cases:

First case: this is the first installation of my product, Inno setup should proceed normally.

Second case: the product is already installed AND the installer contains a newer version. The user cannot choose the destination folder. He can just run the update.

Third case: If the installer contains an older version than the installed one, the update will be disabled and a message should be displayed.

Fourth case: The installer version is the same than the installed version. The user can repair his actual version if needed.

Is it possible to do that with InnoSetup?

svarog
  • 9,477
  • 4
  • 61
  • 77
Ben
  • 3,972
  • 8
  • 43
  • 82

2 Answers2

16

Inno Setup already handles cases 1, 2, and 4 automatically if your AppID is kept the same for the life of the application.
You can also hide the directory and group pages using the following[Setup] directives:

DisableDirPage=auto
DisableGroupPage=auto

See this ISXKB article for more details.

For case 3, assuming your files are versioned correctly, Inno won't downgrade anything, but it won't actually warn the user. To do that, you will need to add code to check this, most likely in the InitializeSetup() event function.

Deanna
  • 23,876
  • 7
  • 71
  • 156
  • 5
    Actually if you use the Script Wizard to create your script then the default for application files is to add the `ignoreversion` flag, in which case a downgrade will actually downgrade all the files. It's still probably a good idea to add a warning message just to confirm that the user really did want to do that, but otherwise it should work fine -- assuming that your app itself can cope with being downgraded (eg. data compatibility concerns). If not, then you should add an error instead of a warning. – Miral Mar 27 '13 at 19:51
  • 1
    @Miral I'd not noticed that. Thanks for the heads up. – Deanna Mar 28 '13 at 09:30
  • Example logic for checking in `InitializeSetup` would be great...I'm assuming there are some definitions already baked into inno for this... – Assimilater Jun 19 '17 at 19:08
  • @Assimilater there is no built in method, but you can write the version to the registry on install, then read it back again and compare. I don't have any code to hand. – Deanna Jun 19 '17 at 22:32
  • If we're left to resort to hacks like that I guess there's really nothing more to say. I can get that much on my own – Assimilater Jun 19 '17 at 22:38
  • One thing to note with this method (which I am using) is that inno (using 5.6.1) compares the "File version" value in the file properties of each file it is looking to upgrade. Therefore .exe build process needs to update this property and not just rely on settings in the inno script. – Dazed Nov 29 '18 at 10:39
10

If you want to have some feedback for user you can try something like that. First of all, your update should have the same AppId name as your Main App. Then you can set some checks, that will display messages to inform user about the state.

#define MyAppVersion "1.2.2.7570"
#define MyAppName "MyApp Update"

[Setup]
AppId=MyApp
AppName={#MyAppName}
AppVersion={#MyAppVersion}
DefaultDirName={reg:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MyApp_is1,InstallLocation}
DisableDirPage=True

[CustomMessages]
MyAppOld=The Setup detected application version 
MyAppRequired=The installation of {#MyAppName} requires MyApp to be installed.%nInstall MyApp before installing this update.%n%n
MyAppTerminated=The setup of update will be terminated.

[Code]
var
InstallLocation: String;

function GetInstallString(): String;
var
InstPath: String;
InstallString: String;
begin
InstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\MyApp_is1');
InstallString := '';
if not RegQueryStringValue(HKLM, InstPath, 'InstallLocation', InstallString) then
RegQueryStringValue(HKCU, InstPath, 'InstallLocation', InstallString);
Result := InstallString;
InstallLocation := InstallString;
end;

function InitializeSetup: Boolean;
var
V: Integer;
sUnInstallString: String;
Version: String;
begin
    if RegValueExists(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows\CurrentVersion\Uninstall\MyApp_is1', 'UninstallString') then begin
      RegQueryStringValue(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows\CurrentVersion\Uninstall\MyApp_is1', 'DisplayVersion', Version);
      if Version =< ExpandConstant('{#MyAppVersion}') then begin 
          Result := True;
          GetInstallString();
       end
       else begin
MsgBox(ExpandConstant('{cm:MyAppOld}'+Version+'.'+#13#10#13#10+'{cm:MyAppRequired}'+'{cm:MyAppTerminated}'), mbInformation, MB_OK);
         Result := False;
  end;
end
else begin
  MsgBox(ExpandConstant('{cm:MyAppRequired}'+'{cm:MyAppTerminated}'), mbInformation, MB_OK);
  Result := False;
end;
end;
RobeN
  • 5,346
  • 1
  • 33
  • 50
  • 1. Check if app installed; 2. Check app version; 3. Compare App version to Update version; 3a. if update newer then install; 3b. if update older then do not install; 3c. if app not present then not install – RobeN Mar 26 '13 at 14:15
  • Inno already automatically remembers the installation directory, rendering your `DefaultDirName` code redundant. You also don't specify a default for the first install. – Deanna Mar 26 '13 at 15:04
  • They don't need to be separate, Inno does it all automatically. If they need to include less files, then just keep the same AppID and `[Setup]` directives. – Deanna Mar 26 '13 at 15:19
  • Also, you can use `WizardForm.PrevAppDir` to retrieve the previous `{app}` folder, which is incidentally a good way to tell whether the app was previously installed as well. However having said that I'm not sure if doing this works from `InitializeSetup`; that may be too early. – Miral Mar 27 '13 at 19:53