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