安装前获取功能安装成本
我们正在为我们的安装制作一个自定义的 boostrapper/外部 UI。
我们希望提供一个“自定义安装”对话框(就像在 MSI 中一样),以允许用户选择他们想要安装或删除的功能。
目前,我们可以从 MSI 数据库本身读取功能(以及其他功能详细信息,如描述)(通过在 Feature
表上运行 SQL 查询)。
但是,我们还想显示安装功能的成本。 Windows Installer“自定义安装”对话框可以执行此操作。
我认为我们可以通过执行以下操作来模仿该行为:
- 选择您想要获取成本的
Feature
- 使用
FeatureComponents
表,获取Component
> 与 1 中的功能关联 - 使用
File
表,添加与 2 中标识的组件关联的文件的FileSize
- 3 中的总和是功能安装的成本
问题:
- 是否有一个 API(来自 DTF 或 MSI.DLL)可供我们在安装之前获取功能的成本? (DTF中有一个
FeatureInfo.GetCost
方法,但您不能直接使用它。必须先安装该产品,然后才能从调用
)FeatureInfo.GetCost
ProductInstallation - 如果没有 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。
We're making a custom boostrapper / external UI for our installation.
We want to provide a "Custom Installation" dialog (like in MSI) to allow the user to choose feature(s) they want to install or remove.
Currently, we are able to read the features (and other feature details like description) from the MSI database itself (by running an SQL query on the Feature
table).
However, we also want to display the cost of installing a feature. Windows Installer "Custom Installation" dialog is capable of doing this.
I think we can mimic the behavior by doing the following:
- Pick a
Feature
that you want to get the cost - Using the
FeatureComponents
table, get theComponent
associated with the feature from 1 - Using the
File
table, add theFileSize
of the files associated with the component identified in 2 - The sum from 3 is the cost of the feature installation
Question:
- Is there an API (either from DTF or MSI.DLL) that we can use to get the cost of a feature PRIOR to installation? (There is a
FeatureInfo.GetCost
method in DTF but you can't use that directly. The product must be installed first before you can callFeatureInfo.GetCost
fromProductInstallation
) - If there is no API, is the procedure given above appropriate or correct to calculate the cost of a feature installation?
Thanks! :)
UPDATE # 1
I think there's a way to get the cost of a feature installation through the API even PRIOR to starting installation. Here's how I did it:
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();
calling info.name
successfully returns the name of the feature. However, calling info.GetCost
will return an InvalidHandlerException
with a message: "selection manager not initialized".
Here's where I'm currently at.
Update #2:
I was getting the InvalidHandlerException
because I am not invoking the needed file costing routines before I call info.GetCost
. Here's my modified code:
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();
I am no longer getting the InvalidHandlerException but all file cost being returned is -1099511627776.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,有一个 API。您需要通过调用 OpenPackage 来获取 MSI 会话。通过这样做,您将可以访问功能列表,从而可以访问 GetCost 方法。
1 陷阱:在计算成本之前,您需要执行 4 个标准操作:CostInitialize、FileCost、CostFinalize 和 <强>安装验证。
Yes, there is an API. You need to get an MSI Session by calling OpenPackage. By doing so, you will have access to the Feature list which will give you access to the GetCost method.
1 Gotcha: You need to perform 4 standard actions before calculating the cost: CostInitialize, FileCost, CostFinalize and InstallValidate.
这不是您正在寻找的答案,但我建议在构建时预先计算功能的大小,并在安装过程中使用预先计算的表。这就是我们在 Burn 中所做的事情在 WiX v3.6 中。它更快更快并且更更稳定。
This isn't the answer you are looking for but I would suggest pre-calculating the sizes of the features at build time and using a precalculated table during install. This is what we do in Burn in WiX v3.6. It is much faster and much more stable.