7

Is there a way to disable the Components Page for Upgrades? I would like to enable upgrades of my software but I don't want to allow the users to change the selection of components in case of an upgrade. Instead the installer you upgrade all existing components from the first installation.

I am worried that it the user selects less components during the upgrade those missing components will stay installed as the old version and you get a mess.

I added the following to my script:

[Setup]
DisableDirPage=auto
DisableProgramGroupPage=auto
DirExistsWarning=auto

I just need a way to disable the components page and use the selection of the previous install (full install) for the upgrade. Is that possible?

I have found a related directive:

[Setup]
UsePreviousTasks=true

UsePreviousTasks is reading the existing section out of the registry which is good. Now I need to find a way to hide the selection window.

Thanks,
Wolfgang

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Wolfgang Reh
  • 168
  • 2
  • 9
  • Note that Inno already displays a warning message if the user selects fewer components than were selected originally (and the default is to select the same set of components as before anyway). So even without hiding the page, if this scenario happens it's because the user has explicitly decided to do that despite warnings. In which case, why not let them have it? – Miral Aug 30 '13 at 23:07

3 Answers3

12

To hide a page from user use the ShouldSkipPage event method. If you return True in this method, the page won't be shown to user. If False, the page will be displayed as usually. Here 's an example of how to check if the installation is an upgrade and if so, skip the Select Components wizard page:

[Setup]
AppId=B75E4823-1BC9-4AC6-A645-94027A16F5A5
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program

; here is the place for your [Components] section and the rest of your script
[Code]
const
  UninstallKey = 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppId")}_is1';

function IsUpgrade: Boolean;
var
  Value: string;
begin
  Result := (RegQueryStringValue(HKLM, UninstallKey, 'UninstallString', Value) or
    RegQueryStringValue(HKCU, UninstallKey, 'UninstallString', Value)) and (Value <> '');
end;

function ShouldSkipPage(PageID: Integer): Boolean;
begin
  Result := (PageID = wpSelectComponents) and IsUpgrade;
end;

Another option you mentioned might be to disable all the controls of the page. The next script shows as the previous one how to check if the installation is an upgrade and if so, disables all the controls on the Select Components wizard page:

[Setup]
AppId=B75E4823-1BC9-4AC6-A645-94027A16F5A5
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program

; here is the place for your [Components] section and the rest of your script
[Code]
const
  UninstallKey = 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppId")}_is1';

function IsUpgrade: Boolean;
var
  Value: string;
begin
  Result := (RegQueryStringValue(HKLM, UninstallKey, 'UninstallString', Value) or
    RegQueryStringValue(HKCU, UninstallKey, 'UninstallString', Value)) and (Value <> '');
end;

procedure DisablePageControls(Page: TNewNotebookPage);
var
  I: Integer;
begin
  Page.Enabled := False;
  for I := 0 to Page.ControlCount - 1 do
    Page.Controls[I].Enabled := False;
end;

procedure InitializeWizard;
begin
  if IsUpgrade then
    DisablePageControls(WizardForm.SelectComponentsPage);
end;
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
TLama
  • 75,147
  • 17
  • 214
  • 392
  • Your `IsUpgrade` fails for 32-bit installations on a 64-bit system. The uninstall key is at HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall... – ygoe Jan 25 '14 at 19:00
  • @LonelyPixel, [`are you sure`](http://msdn.microsoft.com/en-us/library/aa372105(v=vs.85).aspx) ? – TLama Jan 25 '14 at 19:13
  • Yes, I use regedit to verify my findings. And neither this nor your key works properly in the script. I'm stuck. InnoSetup doesn't find the key anywhere. – ygoe Jan 25 '14 at 19:22
  • Using Process Monitor, I see the issue. AppId begins with a `{` and in order to escape it, it must be doubled. Your code doesn't consider this and InnoSetup effectively looks for the key `...Uninstall\{{99...`. – ygoe Jan 25 '14 at 19:29
  • I'm not considering this case because `AppId` in my example doesn't have curly braces. Btw. you were running 64-bit regedit and what you've seen under the redirector node was a 32-bit view. – TLama Jan 25 '14 at 19:46
  • Nevermind, I've corrected your function and posted it as another answer. This now works as expected for me. – ygoe Jan 25 '14 at 19:48
2

The IsUpgrade function mentioned in TLama's answer has a bug. If AppId starts with a "{" which must be doubled, this isn't resolved and they registry key will not be found. Here's a corrected function that works for me:

function IsUpgrade: Boolean;
var
    Value: string;
    UninstallKey: string;
begin
    UninstallKey := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\' +
        ExpandConstant('{#SetupSetting("AppId")}') + '_is1';
    Result := (RegQueryStringValue(HKLM, UninstallKey, 'UninstallString', Value) or
        RegQueryStringValue(HKCU, UninstallKey, 'UninstallString', Value)) and (Value <> '');
end;

Leave the separate const away for this function, it won't work with that extra function call.

Apart from that, 64-bit systems don't seem to cause any issues. If InnoSetup runs in 32-bit mode, the registry virtualisation is in effect and redirects you to the correct key already.

ygoe
  • 18,655
  • 23
  • 113
  • 210
  • Bug it has for you. Not for my example. Besides, you could keep that constant out of the function. You might use the `%s` data type indicator in the constant and `Format` function inside of your function. – TLama Jan 25 '14 at 19:58
  • True, but still a bug. Ask any developer about users who have different (yet valid) use cases than the dev. ;-) And about the registry key: I consider it specific enough to keep it in the function where it's used. It doesn't scatter things so far around. – ygoe Jan 25 '14 at 21:00
0

Something like that:

if CurPageID=wpSelectComponents then
 begin
  if ExtraOptionAvailable() then
  begin
    Wizardform.ComponentsList.Checked[6] := true;
    Wizardform.ComponentsList.ItemEnabled[6] := true;
  end else begin
    Wizardform.ComponentsList.Checked[6] := false;
    Wizardform.ComponentsList.ItemEnabled[6] := false;
  end;
end;
  • it disables the components ... found no way to hide the page :S – Weissbrot90 Aug 30 '13 at 09:34
  • This code could be simplified, no need for the second if statement. – ciruvan Aug 30 '13 at 09:53
  • What is the `ExtraOptionAvailable` ? And how are you detecting it's an upgrade ? Anyway, there's the [`ShouldSkipPage`](http://www.jrsoftware.org/ishelp/index.php?topic=scriptevents&anchor=ShouldSkipPage) event where you can tell the wizard to skip the page you choose. That will *hide* the page from user. – TLama Aug 30 '13 at 09:54