我们正在为我们的安装制作一个自定义的 boostrapper/外部 UI。

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

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

但是,我们还想显示安装功能的成本。Windows Installer“自定义安装”对话框可以执行此操作。

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

  1. 选择一个 Feature 你想要得到的成本
  2. 使用 FeatureComponents 表,得到 Component 与 1 中的特征相关联
  3. 使用 File 表,添加 FileSize 与 2 中标识的组件关联的文件的数量
  4. 3 的总和是功能安装的成本

问题:

  1. 是否有一个 API(来自 DTF 或 MSI.DLL)可供我们在安装之前获取功能的成本?(有一个 FeatureInfo.GetCost DTF 中的方法,但不能直接使用它。必须先安装产品才能调用 FeatureInfo.GetCostProductInstallation)
  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. 。这是我修改后的代码:

  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。

有帮助吗?

解决方案 2

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

1 陷阱:在计算成本之前,您需要执行 4 个标准操作: 成本初始化, 文件成本, 成本最终确定安装验证.

    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();

其他提示

这不是您正在寻找的答案,但我建议在构建时预先计算功能的大小,并在安装过程中使用预先计算的表。这就是我们所做的 烧伤 在 WiX v3.6 中。这是 很多 更快并且 很多 更稳定。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top