安装前获取功能安装成本

时间:2011-01-26 09:53:48

标签: wix installation windows-installer burn dtf

我们正在为我们的安装制作自定义的boostrapper /外部用户界面。

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

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

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

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

  1. 选择要获得费用的Feature
  2. 使用FeatureComponents表,从1
  3. 获取与该功能相关联的Component
  4. 使用File表,添加与2中标识的组件关联的文件的FileSize
  5. 3的总和是功能安装的成本
  6. 问题:

    1. 我们是否可以使用API​​(来自DTF或MSI.DLL)来获取安装前的功能成本? (DTF中有一个FeatureInfo.GetCost方法,但您无法直接使用该方法。必须先安装该产品,然后才能从FeatureInfo.GetCost拨打ProductInstallation
    2. 如果没有API,上面给出的程序是否适当或正确以计算功能安装的成本?
    3. 谢谢! :)

      更新#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。

2 个答案:

答案 0 :(得分:1)

这不是您正在寻找的答案,但我建议您在构建时预先计算要素的大小,并在安装过程中使用预先计算的表格。这就是我们在WiX v3.6中Burn所做的事情。 更快,更多更稳定。

答案 1 :(得分:1)

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

1知识:在计算成本之前,您需要执行4项标准操作: CostInitialize FileCost CostFinalize InstallValidate

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