2

在“Bundle.wxs”中,我有一个带有“MsiPackages”的“链”,其中包含“InstallConditions”。为了让用户决定他/她想要安装/升级哪些包,我想显示其中的属性。

例如,我想读取链中每个 MSI 的“属性”表中的属性“ProductName”和“ProductVersion”,并在链中每个 MSI 的复选框旁边将其显示给用户。该复选框连接到“InstallConditions”中使用的刻录变量。

但问题是,在“应用”步骤之前,我似乎无法访问 MSI 文件。在此步骤之前,它们不会从引导程序应用程序 EXE 中提取。所以,我的问题是,有没有办法以编程方式加载这些值,以便在应用步骤之前将它们显示给用户?我可以使用变量并自己用这些值填充它们,但是这些信息已经在 MSI 中,所以这似乎效率低下。

有没有办法做到这一点?谢谢您的帮助。

<Bundle>

    <Variable Name="InstallProduct1" Type="string" Value="true" />
    <Variable Name="ProductName1" Type="string" Value="My Product 1"/> <!-- Better way? -->
    <Variable Name="ProductVersion1" Type="version" Value="1.2.3.4"/> <!-- Better way? -->

    <Chain>
              <MsiPackage SourceFile="my_product_1.msi"
                          InstallCondition="InstallProduct1">
              </MsiPackage>
    </Chain>

</Bundle>
4

1 回答 1

4

WiX 确实会生成一个 BootstrapperApplicationData.xml 文件,其中包含大量用于构建 exe 的信息,并且包含在运行时可用的文件中。您可以在运行时解析该文件以访问该元数据。由于该文件以及我们所有的程序集和 .msi 文件都放置在一个随机命名的临时文件夹中,因此我们无法提前知道该文件的位置,因此我们必须使用程序集的路径来找到它。然后,您可以解析 XML 以获取元数据。

我在这里有一篇包含更多详细信息的博客文章:https ://www.wrightfully.com/part-3-of-writing-your-own-net-based-installer-with-wix-context-data/

在我的情况下,我使用标签而不是 '',所以我可以使用的一些信息可能不适合您,因此您的体验可能会有所不同。我建议在调试模式下运行临时安装程序并设置断点来检查 XML 的内容,以获得可用内容的完整列表。

这是我如何从 ManagedBootstrapperApplication (c#) 中的文件获取数据的示例。注意:在这个例子中,我的领域对象是 MBAPrereqPackage、BundlePackage 和 PackageFeature,它们每个都在其构造函数中获取一个 XML 节点对象,并将数据进一步解析为对象的属性。

const  XNamespace ManifestNamespace = ( XNamespace) “http://schemas.microsoft.com/wix/2010/BootstrapperApplicationData” ;

public void Initialize()
{

    //
    // parse the ApplicationData to find included packages and features
    //
    var bundleManifestData = this.ApplicationData;
    var bundleDisplayName = bundleManifestData 
                              .Element(ManifestNamespace + “WixBundleProperties“ )
                              .Attribute( “DisplayName“)
                              .Value;

    var mbaPrereqs = bundleManifestData.Descendants(ManifestNamespace + “WixMbaPrereqInformation“)
                                       .Select(x => new MBAPrereqPackage(x))
                                       .ToList();

    //
    //exclude the MBA prereq packages, such as the .Net 4 installer
    //
    var pkgs = bundleManifestData.Descendants(ManifestNamespace + “WixPackageProperties“)
                                 .Select(x => new BundlePackage(x))
                                 .Where(pkg => !mbaPrereqs.Any(preReq => preReq.PackageId == pkg.Id));

    //
    // Add the packages to a collection of BundlePackages
    //
    BundlePackages.AddRange(pkgs);

    //
    // check for features and associate them with their parent packages
    //
    var featureNodes = bundleManifestData.Descendants(ManifestNamespace + “WixPackageFeatureInfo“);
    foreach ( var featureNode in featureNodes)
    {
       var feature = new PackageFeature(featureNode);
       var parentPkg = BundlePackages.First(pkg => pkg.Id == feature.PackageId);
       parentPkg.AllFeatures.Add(feature);
       feature.Package = parentPkg;
    }
}

/// 
/// Fetch BootstrapperApplicationData.xml and parse into XDocument.
/// 
public XElement ApplicationData
{
    get
    {
        var workingFolder = Path.GetDirectoryName(this.GetType().Assembly.Location);
        var bootstrapperDataFilePath = Path.Combine(workingFolder, “BootstrapperApplicationData.xml”);

        using (var reader = new StreamReader(bootstrapperDataFilePath))
        {
            var xml = reader.ReadToEnd();
            var xDoc = XDocument.Parse(xml);
            return xDoc.Element(ManifestNamespace + “BootstrapperApplicationData“);                   
        }
    }
}
于 2013-11-07T12:58:01.403 回答