| 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.Data; |
| 5 | using System.Globalization; |
| 6 | using System.Collections; |
| 7 | using System.Windows.Forms; |
| 8 | using WixToolset.Dtf.WindowsInstaller; |
| 9 | |
| 10 | namespace WixToolset.Dtf.Tools.Inventory |
| 11 | { |
| 12 | /// <summary> |
| 13 | /// Provides inventory data about products installed or advertised on the system. |
| 14 | /// </summary> |
| 15 | public class ProductsInventory : IInventoryDataProvider |
| 16 | { |
| 17 | public ProductsInventory() |
| 18 | { |
| 19 | } |
| 20 | |
| 21 | public string Description |
| 22 | { |
| 23 | get { return "Installed products"; } |
| 24 | } |
| 25 | |
| 26 | public string[] GetNodes(InventoryDataLoadStatusCallback statusCallback) |
| 27 | { |
| 28 | statusCallback(0, "Products"); |
| 29 | ArrayList nodes = new ArrayList(); |
| 30 | nodes.Add("Products"); |
| 31 | foreach(ProductInstallation product in ProductInstallation.AllProducts) |
| 32 | { |
| 33 | nodes.Add("Products\\" + MsiUtils.GetProductName(product.ProductCode)); |
| 34 | } |
| 35 | statusCallback(nodes.Count, String.Empty); |
| 36 | return (string[]) nodes.ToArray(typeof(string)); |
| 37 | } |
| 38 | |
| 39 | public bool IsNodeSearchable(string searchRoot, string searchNode) |
| 40 | { |
| 41 | return true; |
| 42 | } |
| 43 | |
| 44 | public DataView GetData(string nodePath) |
| 45 | { |
| 46 | string[] path = nodePath.Split('\\'); |
| 47 | |
| 48 | if(path.Length == 1 && path[0] == "Products") |
| 49 | { |
| 50 | return this.GetAllProductsData(); |
| 51 | } |
| 52 | else if(path.Length == 2 && path[0] == "Products") |
| 53 | { |
| 54 | return this.GetProductData(MsiUtils.GetProductCode(path[1])); |
| 55 | } |
| 56 | return null; |
| 57 | } |
| 58 | |
| 59 | private DataView GetAllProductsData() |
| 60 | { |
| 61 | DataTable table = new DataTable("Products"); |
| 62 | table.Locale = CultureInfo.InvariantCulture; |
| 63 | table.Columns.Add("ProductsProductName", typeof(string)); |
| 64 | table.Columns.Add("ProductsProductCode", typeof(string)); |
| 65 | |
| 66 | foreach (ProductInstallation product in ProductInstallation.AllProducts) |
| 67 | { |
| 68 | string productName = MsiUtils.GetProductName(product.ProductCode); |
| 69 | table.Rows.Add(new object[] { productName, product.ProductCode }); |
| 70 | } |
| 71 | return new DataView(table, "", "ProductsProductName ASC", DataViewRowState.CurrentRows); |
| 72 | } |
| 73 | |
| 74 | private DataView GetProductData(string productCode) |
| 75 | { |
| 76 | DataTable table = new DataTable("ProductProperties"); |
| 77 | table.Locale = CultureInfo.InvariantCulture; |
| 78 | table.Columns.Add("ProductPropertiesProperty", typeof(string)); |
| 79 | table.Columns.Add("ProductPropertiesValue", typeof(string)); |
| 80 | |
| 81 | // Add a fake "ProductCode" install property, just for display convenience. |
| 82 | table.Rows.Add(new object[] { "ProductCode", productCode }); |
| 83 | |
| 84 | ProductInstallation product = new ProductInstallation(productCode); |
| 85 | |
| 86 | foreach(string property in new string[] |
| 87 | { |
| 88 | "AssignmentType", |
| 89 | "DiskPrompt", |
| 90 | "HelpLink", |
| 91 | "HelpTelephone", |
| 92 | "InstalledProductName", |
| 93 | "InstallDate", |
| 94 | "InstallLocation", |
| 95 | "InstallSource", |
| 96 | "Language", |
| 97 | "LastUsedSource", |
| 98 | "LastUsedType", |
| 99 | "LocalPackage", |
| 100 | "MediaPackagePath", |
| 101 | "PackageCode", |
| 102 | "PackageName", |
| 103 | "ProductIcon", |
| 104 | "ProductID", |
| 105 | "ProductName", |
| 106 | "Publisher", |
| 107 | "RegCompany", |
| 108 | "RegOwner", |
| 109 | "State", |
| 110 | "transforms", |
| 111 | "Uninstallable", |
| 112 | "UrlInfoAbout", |
| 113 | "UrlUpdateInfo", |
| 114 | "Version", |
| 115 | "VersionMinor", |
| 116 | "VersionMajor", |
| 117 | "VersionString" |
| 118 | }) |
| 119 | { |
| 120 | try |
| 121 | { |
| 122 | string value = product[property]; |
| 123 | table.Rows.Add(new object[] { property, (value != null ? value : "") }); |
| 124 | } |
| 125 | catch(InstallerException iex) |
| 126 | { |
| 127 | table.Rows.Add(new object[] { property, iex.Message }); |
| 128 | } |
| 129 | catch(ArgumentException) { } |
| 130 | } |
| 131 | return new DataView(table, "", "ProductPropertiesProperty ASC", DataViewRowState.CurrentRows); |
| 132 | } |
| 133 | |
| 134 | public string GetLink(string nodePath, DataRow row) |
| 135 | { |
| 136 | string[] path = nodePath.Split('\\'); |
| 137 | |
| 138 | if(path.Length == 1 && path[0] == "Products") |
| 139 | { |
| 140 | return String.Format(@"Products\{0}", MsiUtils.GetProductName((string) row["ProductsProductCode"])); |
| 141 | } |
| 142 | return null; |
| 143 | } |
| 144 | } |
| 145 | } |