2

製品コードを指定して Windows インストーラ コンポーネント コードを取得する方法を探しています。(実際には、コンポーネント コードを含まないショートカットを使用して、インストールされた製品のコンポーネント パスを取得しようとしていますが、これはより長い話です。)

私は WiX DTF (Microsoft.Deployment.WindowsInstaller) アセンブリに出くわしましたが、これは MSI を実行するための良い方法のようです。次のコードを書いたとき、私は非常に期待していました。

Session product = Installer.OpenProduct(productCode);
ComponentInfoCollection components = product.Components;
ComponentInfo component = components.FirstOrDefault();

ComponentInfo からコンポーネント コードを取得できることを願っていました。残念ながら、これを行う方法はありません。

WiX DTF クラスを使用してコンポーネント コードを取得することは可能ですか? (または、他の方法でそれに到達する...)

4

2 に答える 2

2

1対1の関係ではないので、「製品」に対して「コンポーネント」を取得したいという欲求が理解できません。つまり、これはあなたが求めることを行うことができると言った:

const string PRODUCT_CODE = "{EBBD327E-F220-4567-88F8-CEE3BE560F81}";
var comps = from c in ComponentInstallation.AllComponents
            where c.Product.ProductCode == PRODUCT_CODE
            select c;
string componentId = comps.FirstOrDefault().ComponentCode;
于 2016-01-08T15:59:23.163 に答える
0

以下を使用してコンポーネントコードを取得できることがわかりました。

private string GetComponentIdFromMsi()
{
    using (Session product = Installer.OpenProduct(_productCode))
    using (Database database = product.Database)
    {
        var featureComponentsRecords = GetFeatureComponents(database);
        var featureComponentsRecord = featureComponentsRecords.Single(x => x.Feature == _feature);
        var componentRecords = GetComponents(database);
        var componentId = componentRecords.Single(x => x.Component == featureComponentsRecord.Component).ComponentId;
        return componentId;
    }
}

private IEnumerable<FeatureComponentsRecord> GetFeatureComponents(Database database)
{
    var list = database.ExecuteQuery("SELECT `Feature_`, `Component_` FROM `FeatureComponents`");
    const int columnCount = 2;
    const int featureOffset = 0;
    const int componentOffset = 1;
    int rowCount = list.Count / columnCount;

    for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
    {
        var rowOffset = rowIndex * columnCount;
        yield return new FeatureComponentsRecord((string)list[rowOffset + featureOffset], (string)list[rowOffset + componentOffset]);
    }
}

private IEnumerable<ComponentRecord> GetComponents(Database database)
{
    var list = database.ExecuteQuery("SELECT `Component`, `ComponentId` FROM `Component`");
    const int columnCount = 2;
    const int componentOffset = 0;
    const int componentIdOffset = 1;
    int rowCount = list.Count / columnCount;

    for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
    {
        var rowOffset = rowIndex * columnCount;
        yield return new ComponentRecord((string)list[rowOffset + componentOffset], (string)list[rowOffset + componentIdOffset]);
    }
}

private class FeatureComponentsRecord
{
    public FeatureComponentsRecord(string feature, string component)
    {
        Feature = feature;
        Component = component;
    }

    public string Feature { get; private set; }
    public string Component { get; private set; }
}

private class ComponentRecord
{
    public ComponentRecord(string component, string componentId)
    {
        Component = component;
        ComponentId = componentId;
    }

    public string Component { get; private set; }
    public string ComponentId { get; private set; }
}
于 2016-01-08T15:38:50.230 に答える