问题
I have been trying to find a way to get a Windows Installer component code given a product code. (I'm actually trying to get the component path for an installed product using a shortcut that doesn't contain the component code, but this is a longer story.)
I have come across the WiX DTF (Microsoft.Deployment.WindowsInstaller) assembly and this looks like a nice way to get MSI stuff done. I was very hopeful when I wrote the following code:
Session product = Installer.OpenProduct(productCode);
ComponentInfoCollection components = product.Components;
ComponentInfo component = components.FirstOrDefault();
I hoped I could get the component code from ComponentInfo. Unfortunately I see no way to do this.
Is it possible to get the component code using the WiX DTF classes? (Or any other way come to that...)
回答1:
I don't understand the desire to get "the component" for "the product" as it's not a 1:1 relationship. That said this could would do what you ask:
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;
回答2:
I have found it is possible to get the component code using the following:
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; }
}
来源:https://stackoverflow.com/questions/34680164/get-component-code-using-wix-dtf