9

Wix Standard Bootstrapperアプリケーションのソースを見ると、各パッケージにDisplayNameプロパティがあるようです。

pPackage->sczDisplayName

ただし、WiXセットアッププロジェクトで使用されるBootstrapperCoredllにはこのプロパティがありません。マネージコードのバンドルからこのプロパティを抽出する方法はありますか?

4

2 に答える 2

13

コードをC#に移植しBal、C++コードとまったく同じように機能させるようにしました。

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.XPath;

public class BootstrapperApplicationData
{
    public const string defaultFileName = "BootstrapperApplicationData.xml";
    public const string xmlNamespace = 
        "http://schemas.microsoft.com/wix/2010/BootstrapperApplicationData";

    private static DirectoryInfo defaultFolder;
    public static DirectoryInfo DefaultFolder
    {
        get
        {
            if (defaultFolder == null)
            {
                defaultFolder = (new FileInfo(Assembly.GetExecutingAssembly().Location)).Directory;
            }
            return defaultFolder;
        }
    }

    private static FileInfo defaultFile;
    public static FileInfo DefaultFile
    {
        get
        {
            if (defaultFile == null)
            {
                defaultFile = new FileInfo(Path.Combine(DefaultFolder.FullName, defaultFileName));
            }
            return defaultFile;
        }
    }

    public FileInfo DataFile { get; protected set; }
    public Bundle Data { get; protected set; }

    public BootstrapperApplicationData() : this(DefaultFile) { }

    public BootstrapperApplicationData(FileInfo fiBootstrapperApplicationData)
    {
        DataFile = fiBootstrapperApplicationData;
        using (FileStream fs = DataFile.OpenRead())
        {
            Data = ParseBundleFromStream(fs);
        }
    }

    public static Bundle ParseBundleFromStream(Stream stream)
    {
        XPathDocument manifest = new XPathDocument(stream);
        XPathNavigator root = manifest.CreateNavigator();
        return ParseBundleFromXml(root);
    }

    public static Bundle ParseBundleFromXml(XPathNavigator root)
    {
        Bundle bundle = new Bundle();

        XmlNamespaceManager namespaceManager = new XmlNamespaceManager(root.NameTable);
        namespaceManager.AddNamespace("p", xmlNamespace);
        XPathNavigator bundleNode = root.SelectSingleNode("/p:BootstrapperApplicationData/p:WixBundleProperties", namespaceManager);

        if (bundleNode == null)
        {
            throw new Exception("Failed to select bundle information");
        }

        bool? perMachine = GetYesNoAttribute(bundleNode, "PerMachine");
        if (perMachine.HasValue)
        {
            bundle.PerMachine = perMachine.Value;
        }

        string name = GetAttribute(bundleNode, "DisplayName");
        if (name != null)
        {
            bundle.Name = name;
        }

        string logVariable = GetAttribute(bundleNode, "LogPathVariable");
        if (logVariable != null)
        {
            bundle.LogVariable = logVariable;
        }
        else
        {
            //wix would actually debug "Failed to select bundle information" and return with E_NOTFOUND, but I think it's a (harmless) bug
        }

        Package[] packages = ParsePackagesFromXml(root);
        bundle.Packages = packages;

        return bundle;
    }

    public static Package[] ParsePackagesFromXml(XPathNavigator root)
    {
        List<Package> packages = new List<Package>();

        XmlNamespaceManager namespaceManager = new XmlNamespaceManager(root.NameTable);
        namespaceManager.AddNamespace("p", xmlNamespace);
        XPathNodeIterator nodes = root.Select("/p:BootstrapperApplicationData/p:WixPackageProperties", namespaceManager);

        foreach (XPathNavigator node in nodes)
        {
            Package package = new Package();

            string id = GetAttribute(node, "Package");
            if (id == null)
            {
                throw new Exception("Failed to get package identifier for package");
            }
            package.Id = id;

            string displayName = GetAttribute(node, "DisplayName");
            if (displayName != null)
            {
                package.DisplayName = displayName;
            }

            string description = GetAttribute(node, "Description");
            if (description != null)
            {
                package.Description = description;
            }

            PackageType? packageType = GetPackageTypeAttribute(node, "PackageType");
            if (!packageType.HasValue)
            {
                throw new Exception("Failed to get package type for package");
            }
            package.Type = packageType.Value;

            bool? permanent = GetYesNoAttribute(node, "Permanent");
            if (!permanent.HasValue)
            {
                throw new Exception("Failed to get permanent settings for package");
            }
            package.Permanent = permanent.Value;

            bool? vital = GetYesNoAttribute(node, "Vital");
            if (!vital.HasValue)
            {
                throw new Exception("Failed to get vital setting for package");
            }
            package.Vital = vital.Value;

            bool? displayInternalUI = GetYesNoAttribute(node, "DisplayInternalUI");
            if (!displayInternalUI.HasValue)
            {
                throw new Exception("Failed to get DisplayInternalUI setting for package");
            }
            package.DisplayInternalUI = displayInternalUI.Value;

            string productCode = GetAttribute(node, "ProductCode");
            if (productCode != null)
            {
                package.ProductCode = productCode;
            }

            string upgradeCode = GetAttribute(node, "UpgradeCode");
            if (upgradeCode != null)
            {
                package.UpgradeCode = upgradeCode;
            }

            string version = GetAttribute(node, "Version");
            if (version != null)
            {
                package.Version = version;
            }

            packages.Add(package);
        }

        return packages.ToArray();
    }

    public static string GetAttribute(XPathNavigator node, string attributeName)
    {
        XPathNavigator attribute = node.SelectSingleNode("@" + attributeName);

        if (attribute == null)
        {
            return null;
        }

        return attribute.Value;
    }

    public static bool? GetYesNoAttribute(XPathNavigator node, string attributeName)
    {
        string attributeValue = GetAttribute(node, attributeName);

        if (attributeValue == null)
        {
            return null;
        }

        return attributeValue.Equals("yes", StringComparison.InvariantCulture);
    }

    public static PackageType? GetPackageTypeAttribute(XPathNavigator node, string attributeName)
    {
        string attributeValue = GetAttribute(node, attributeName);

        if (attributeValue == null)
        {
            return null;
        }

        if (attributeValue.Equals("Exe", StringComparison.InvariantCulture))
        {
            return PackageType.EXE;
        }
        else if (attributeValue.Equals("Msi", StringComparison.InvariantCulture))
        {
            return PackageType.MSI;
        }
        else if (attributeValue.Equals("Msp", StringComparison.InvariantCulture))
        {
            return PackageType.MSP;
        }
        else if (attributeValue.Equals("Msu", StringComparison.InvariantCulture))
        {
            return PackageType.MSU;
        }
        else
        {
            return 0;
        }
    }

    public enum PackageType
    {
        EXE,
        MSI,
        MSP,
        MSU,
    }

    public class Package
    {
        public string Id;
        public string DisplayName;
        public string Description;
        public PackageType Type;
        public bool Permanent;
        public bool Vital;
        public bool DisplayInternalUI;

        //not available until WiX 3.9.421.0
        public string ProductCode;
        public string UpgradeCode;
        public string Version;
    }

    public class Bundle
    {
        public bool PerMachine;
        public string Name;
        public string LogVariable;
        public Package[] Packages;
    }
}
于 2013-07-09T12:31:19.413 に答える
5

ビルドプロセス中に生成されたBootstrapperApplicationData.xmlファイルは、BA.dllの横に配置されます。そのXMLファイルをロードして、バンドルおよびバンドル内のパッケージに関する多くの情報を取得できます。

BootstrapperApplicationData.xmlネイティブコードをロードするには、WiXツールセットで提供されているBalManifestLoad()メソッドを使用します。balutil.libあなたはでコードを見ることができますsrc\ext\BalExtension\balutil\balutil.cpp。次に、inを使用して、XMLファイルを一連の便利な構造体に解析することBalInfoParseFromXml()もできます。balutil.libあなたはでコードを見ることができますsrc\ext\BalExtension\balutil\balinfo.cpp

于 2013-03-15T07:04:24.033 に答える