1

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

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

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

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

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

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

问题:

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

4

2 回答 2

3

是的,有一个 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();
于 2011-02-11T09:36:16.830 回答
2

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

于 2011-02-10T20:47:37.390 回答