【问题标题】:Get feature installation cost prior to installation安装前获取功能安装成本
【发布时间】:2011-01-26 09:53:48
【问题描述】:

我们正在为我们的安装制作自定义助推器/外部 UI。

我们希望提供一个“自定义安装”对话框(如在 MSI 中),以允许用户选择他们想要安装或删除的功能。

目前,我们能够从 MSI 数据库本身(通过在 Feature 表上运行 SQL 查询)读取功能(以及其他功能详细信息,如描述)。

但是,我们还想显示安装某个功能的成本。 Windows Installer 的“自定义安装”对话框可以做到这一点。

我认为我们可以通过执行以下操作来模仿这种行为:

  1. 选择一个您想获得费用的Feature
  2. 使用FeatureComponents 表,从1 中获取与特征关联的Component
  3. 使用File 表,添加与2 中标识的组件关联的文件的FileSize
  4. 3 的总和是功能安装的成本

问题:

  1. 是否有一个 API(来自 DTF 或 MSI.DLL)可以用来在安装之前获取功能的成本? (DTF中有FeatureInfo.GetCost方法,但不能直接使用,必须先安装产品才能从ProductInstallation调用FeatureInfo.GetCost
  2. 如果没有 API,上面给出的过程是否适合或正确计算功能安装的成本?

谢谢! :)

更新 #1

我认为有一种方法可以在开始安装之前通过 API 获取功能安装的成本。我是这样做的:

Installer.SetInternalUI(InstallUIOptions.Silent);

Session s = Installer.OpenPackage(@"C:\a.msi", false);

foreach (FeatureInfo info in s.Features)
{
    MessageBox.Show(info.Name);
    MessageBox.Show(info.GetCost(false, false, InstallState.Unknown).ToString());
}
s.Close();

调用info.name 成功返回功能名称。但是,调用 info.GetCost 将返回带有消息的 InvalidHandlerException:“选择管理器未初始化”。

这是我目前所在的位置。

更新 #2:

我得到了InvalidHandlerException,因为我在调用info.GetCost 之前没有调用所需的file costing routines。这是我修改后的代码:

  Installer.SetInternalUI(InstallUIOptions.Silent);

  Session s = Installer.OpenPackage(@"C:\1.msi", false);
  s["ROOTDRIVE"] = @"C:\";
  s.DoAction("CostInitialize");
  s.DoAction("FileCost");
  s.DoAction("CostFinalize");

  foreach (FeatureInfo info in s.Features)
  {
       long cost = info.GetCost(false, false, InstallState.Local);
       MessageBox.Show(info.Title + " " + cost);
  }
  s.Close();

我不再收到 InvalidHandlerException 但返回的所有文件成本为 -1099511627776。

【问题讨论】:

    标签: wix installation windows-installer burn dtf


    【解决方案1】:

    是的,有一个 API。您需要通过调用 OpenPackage 来获取 MSI 会话。通过这样做,您将可以访问功能列表,这将使您可以访问 GetCost 方法。

    1 个陷阱:在计算成本之前,您需要执行 4 个标准操作:CostInitializeFileCostCostFinalizeInstallValidate

        Installer.SetInternalUI(InstallUIOptions.Silent);
    
        Session s = Installer.OpenPackage(@"C:\1.msi", false);
        s.DoAction("CostInitialize");
        s.DoAction("FileCost");
        s.DoAction("CostFinalize");
        s.DoAction("InstallValidate");
    
        foreach (FeatureInfo info in s.Features)
        {
            long cost = info.GetCost(false, false, InstallState.Local);
            MessageBox.Show(info.Title + " " + cost);
        }
        s.Close();
    

    【讨论】:

      【解决方案2】:

      这不是您要寻找的答案,但我建议在构建时预先计算功能的大小并在安装期间使用预先计算的表格。这就是我们在 WiX v3.6 中的 Burn 中所做的。它快得多而且更稳定。

      【讨论】:

      • 这正是我们最终所做的。通过调用 s.DoAction("InstallValidate") 解决了大小问题。预先计算最有意义,因为调用 OpenPackage 实际上会“启动”引擎(MSIEXEC),这在某些情况下可能会出现问题,并且还需要一些时间来“交互式”地计算成本。感谢您的建议! :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-30
      相关资源
      最近更新 更多