2016-01-08 3 views
1

Я пытаюсь найти способ получить код компонента установщика Windows с кодом продукта. (Я пытаюсь получить путь к компоненту для установленного продукта, используя ярлык, который не содержит код компонента, но это a longer story.)Получить код компонента с помощью WiX DTF

Я столкнулся с WiX DTF (Microsoft.Deployment.WindowsInstaller), и это выглядит как хороший способ получить материал MSI. Я очень надеюсь, когда я написал следующий код:

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

Я надеялся, я мог бы получить код компонента из ComponentInfo. К сожалению, я не вижу возможности сделать это.

Возможно ли получить код компонента с использованием классов WiX DTF? (Или любой другой способ прийти к этому ...)

+0

Я не понимаю желания получить первый компонент. У установщиков много компонентов. –

ответ

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; } 
} 
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; 
+0

Я исхожу из предположения, что есть только один компонент, потому что из ярлыка, который я анализирую, не возвращает идентификатор компонента (см. Http://stackoverflow.com/q/34638433/3051702). Я бы предпочел не перечислять все компоненты, если я могу избежать этого, поскольку он занимает относительно много времени. Я отправил ответ, который смотрит на базу данных. Я еще не знаю, что произойдет, если в таблице Component есть несколько строк, но в моем случае я не думаю, что это вызывает беспокойство. – fractor

+0

Я думаю, что комментарий, который я оставил в другом потоке, будет полезен. Вы должны иметь возможность перемещаться по таблицам, чтобы перейти от идентификатора значка обратно к пути к ключу компонента, чтобы узнать, кем является владелец ярлыка. Для меня просто странно, что API MSI немного лучше. Возможно, есть другой способ, чтобы я обратился к людям, о которых я упоминал. –

+0

Но я думаю, вы говорите, что не обязательно один компонентный путь, соответствующий значку, потому что несколько компонентов могут использовать один и тот же значок. – fractor