Inno Setup组件之间的动态依赖关系

时间:2013-04-01 18:49:46

标签: windows inno-setup

我有三个组成部分。其中两个都依赖于第三个。当检查其他两个组件中的任何一个是否安装时,是否有一种以编程方式自动检查第三个组件的框?

此行为类似于嵌套组件的行为,但这些行为处于同一级别,我无法使用该功能。如果Inno为组件间依赖提供了一种方法,那会很好,但在那之前......

更新
也许我想象的一个虚构的例子会有所帮助:

[Components]
Name: "parent1"; Description: "app 1"
Name: "parent2"; Description: "app 2"; Depends: parent1
Name: "parent2\child"; Description: "feature"
Name: "parent3"; Description: "app 3"; Depends: parent1
Name: "parent3\child"; Description: "feature"

2 个答案:

答案 0 :(得分:1)

默认情况下,选择子组件也会自动选择其父组件(尽管您可以禁用它)。这听起来就像你想要的行为 - 你只是在向后思考它。

假设您有组件A和B,它们是独立的。您还有组件C和D,每个组件可以相互单独安装,但需要安装组件B.

[Components]
Name: "A"; Description: "app 1"
Name: "B"; Description: "app 2"
Name: "B\C"; Description: "feature C of app 2"
Name: "B\D"; Description: "feature D of app 2"

根据这种安排,如果用户愿意,用户可以自己选择A或B;他们也可以选择添加C或D(或不添加)。但是选择C或D也会强制选择B.

(注意:这假设您有其他条目以所有这些为条件,特别是B本身。如果您只是自己测试复选框并且尚未添加Components:条件,那么您必须将Flags: checkablealone添加到B才能获得所需的行为。)

如果您更接近上述示例,请尝试以下操作:

[Components]
Name: "app1"; Description: "app 1"
Name: "app1\app2"; Description: "app 2"
Name: "app1\app2\child"; Description: "feature"
Name: "app1\app3"; Description: "app 3"
Name: "app1\app3\child"; Description: "feature"

App 1可以单独安装,app 2可以与app 3分开安装 - 但是选择app 2或app 3也会强制app 1加入。 (是的,这将显示为一个可见的层次结构 - 但你可能应该显示,以便用户知道为什么他们的选择被强制这样做。)

另一种可能性:如果用户没有理由需要自己安装app1,那么你可以完全从组件中删除它。只需将条件从Components: app1更改为Components: app2 or app3即可。 (或者,如果app2和app3是唯一的选择,并且它们都需要app1,那么完全删除条件。)

答案 1 :(得分:0)

procedure InitializeWizard();
begin
  WizardForm.ComponentsList.OnClickCheck := @ComponentsClickCheck;
end;

procedure ComponentsClickCheck(Sender: TObject);
var
  ListBox: TNewCheckListBox;
  parent1_top: Integer;
  parent2_top: Integer;
  parent3_top: Integer;
begin
  ListBox := TNewCheckListBox(Sender);
  parent1_top := 0;
  parent2_top := 1;
  parent3_top := 3;
  (* Check if parent2_top was selected. *)
  if (ListBox.State[parent2_top] = cbChecked) or
    (ListBox.State[parent2_top] = cbGrayed) then begin
    (* Check a dependent component. *)
    ListBox.CheckItem(parent1_top, coCheckWithChildren);
  end;
  (* Check if parent3_top was selected. *)
  if (ListBox.State[parent3_top] = cbChecked) or
    (ListBox.State[parent3_top] = cbGrayed) then begin
    (* Check a dependent component. *)
    ListBox.CheckItem(parent1_top, coCheckWithChildren);
  end;
end;

在取消选择“依赖”组件之前,“依赖性”变得不可改变会产生一个副作用。更改依赖项的Enabled状态以进行视觉说明也很有用。