1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
using System;
using System.IO;
using System.Data;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Forms;
using WixToolset.Dtf.WindowsInstaller;
namespace WixToolset.Dtf.Tools.Inventory
{
/// <summary>
/// Provides inventory data about features of products installed on the system.
/// </summary>
public class FeaturesInventory : IInventoryDataProvider
{
private static object syncRoot = new object();
public FeaturesInventory()
{
}
public string Description
{
get { return "Features of installed products"; }
}
public string[] GetNodes(InventoryDataLoadStatusCallback statusCallback)
{
statusCallback(0, @"Products\...\Features");
ArrayList nodes = new ArrayList();
foreach (ProductInstallation product in ProductInstallation.AllProducts)
{
nodes.Add(String.Format(@"Products\{0}\Features", MsiUtils.GetProductName(product.ProductCode)));
}
statusCallback(nodes.Count, String.Empty);
return (string[]) nodes.ToArray(typeof(string));
}
public bool IsNodeSearchable(string searchRoot, string searchNode)
{
return true;
}
public DataView GetData(string nodePath)
{
string[] path = nodePath.Split('\\');
if(path.Length == 3 && path[0] == "Products" && path[2] == "Features")
{
return GetProductFeaturesData(MsiUtils.GetProductCode(path[1]));
}
return null;
}
public DataView GetProductFeaturesData(string productCode)
{
DataTable table = new DataTable("ProductFeatures");
table.Locale = CultureInfo.InvariantCulture;
table.Columns.Add("ProductFeaturesFeatureTitle", typeof(string));
table.Columns.Add("ProductFeaturesFeatureName", typeof(string));
table.Columns.Add("ProductFeaturesInstallState", typeof(string));
try
{
IntPtr hWnd = IntPtr.Zero;
Installer.SetInternalUI(InstallUIOptions.Silent, ref hWnd);
lock(syncRoot) // Only one Installer session can be active at a time
{
using(Session session = Installer.OpenProduct(productCode))
{
session.DoAction("CostInitialize");
session.DoAction("FileCost");
session.DoAction("CostFinalize");
IList<string> featuresAndTitles = session.Database.ExecuteStringQuery(
"SELECT `Title`, `Feature` FROM `Feature`");
for(int i = 0; i < featuresAndTitles.Count; i += 2)
{
InstallState featureState = session.Features[featuresAndTitles[i + 1]].CurrentState;
table.Rows.Add(new object[] { featuresAndTitles[i], featuresAndTitles[i+1],
(featureState == InstallState.Advertised ? "Advertised" : featureState.ToString()) });
}
}
}
return new DataView(table, "", "ProductFeaturesFeatureTitle ASC", DataViewRowState.CurrentRows);
}
catch(InstallerException) { }
catch(IOException) { }
return null;
}
public string GetLink(string nodePath, DataRow row)
{
string[] path = nodePath.Split('\\');
if(path.Length == 3 && path[0] == "Products" && path[2] == "Features")
{
return String.Format(@"Products\{0}\Features\{1}", path[1], row["ProductFeaturesFeatureName"]);
}
return null;
}
}
}
|