diff options
Diffstat (limited to 'src/samples/Dtf/Inventory/patches.cs')
-rw-r--r-- | src/samples/Dtf/Inventory/patches.cs | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/src/samples/Dtf/Inventory/patches.cs b/src/samples/Dtf/Inventory/patches.cs new file mode 100644 index 00000000..f01a4798 --- /dev/null +++ b/src/samples/Dtf/Inventory/patches.cs | |||
@@ -0,0 +1,227 @@ | |||
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.Security; | ||
6 | using System.Data; | ||
7 | using System.Collections; | ||
8 | using System.Globalization; | ||
9 | using System.Windows.Forms; | ||
10 | using WixToolset.Dtf.WindowsInstaller; | ||
11 | |||
12 | namespace WixToolset.Dtf.Samples.Inventory | ||
13 | { | ||
14 | /// <summary> | ||
15 | /// Provides inventory data about patches installed on the system. | ||
16 | /// </summary> | ||
17 | public class PatchesInventory : IInventoryDataProvider | ||
18 | { | ||
19 | public PatchesInventory() | ||
20 | { | ||
21 | } | ||
22 | |||
23 | public string Description | ||
24 | { | ||
25 | get { return "Installed patches"; } | ||
26 | } | ||
27 | |||
28 | public string[] GetNodes(InventoryDataLoadStatusCallback statusCallback) | ||
29 | { | ||
30 | ArrayList nodes = new ArrayList(); | ||
31 | statusCallback(nodes.Count, @"Products\...\Patches"); | ||
32 | foreach (ProductInstallation product in ProductInstallation.AllProducts) | ||
33 | { | ||
34 | string productName = MsiUtils.GetProductName(product.ProductCode); | ||
35 | |||
36 | bool addedRoot = false; | ||
37 | foreach (PatchInstallation productPatch in PatchInstallation.GetPatches(null, product.ProductCode, null, UserContexts.All, PatchStates.Applied)) | ||
38 | { | ||
39 | if (!addedRoot) nodes.Add(String.Format(@"Products\{0}\Patches", productName)); | ||
40 | nodes.Add(String.Format(@"Products\{0}\Patches\{1}", productName, productPatch.PatchCode)); | ||
41 | } | ||
42 | } | ||
43 | |||
44 | statusCallback(nodes.Count, "Patches"); | ||
45 | |||
46 | string[] allPatches = GetAllPatchesList(); | ||
47 | if(allPatches.Length > 0) | ||
48 | { | ||
49 | nodes.Add("Patches"); | ||
50 | foreach(string patchCode in allPatches) | ||
51 | { | ||
52 | nodes.Add(String.Format(@"Patches\{0}", patchCode)); | ||
53 | nodes.Add(String.Format(@"Patches\{0}\Patched Products", patchCode)); | ||
54 | } | ||
55 | statusCallback(nodes.Count, String.Empty); | ||
56 | } | ||
57 | return (string[]) nodes.ToArray(typeof(string)); | ||
58 | } | ||
59 | |||
60 | public bool IsNodeSearchable(string searchRoot, string searchNode) | ||
61 | { | ||
62 | return true; | ||
63 | } | ||
64 | |||
65 | public DataView GetData(string nodePath) | ||
66 | { | ||
67 | string[] path = nodePath.Split('\\'); | ||
68 | |||
69 | if(path.Length == 3 && path[0] == "Products" && path[2] == "Patches") | ||
70 | { | ||
71 | return this.GetProductPatchData(path[1]); | ||
72 | } | ||
73 | else if(path.Length == 4 && path[0] == "Products" && path[2] == "Patches") | ||
74 | { | ||
75 | return this.GetPatchData(path[3]); | ||
76 | } | ||
77 | else if(path.Length == 1 && path[0] == "Patches") | ||
78 | { | ||
79 | return this.GetAllPatchesData(); | ||
80 | } | ||
81 | else if(path.Length == 2 && path[0] == "Patches") | ||
82 | { | ||
83 | return this.GetPatchData(path[1]); | ||
84 | } | ||
85 | else if(path.Length == 3 && path[0] == "Patches" && path[2] == "Patched Products") | ||
86 | { | ||
87 | return this.GetPatchTargetData(path[1]); | ||
88 | } | ||
89 | return null; | ||
90 | } | ||
91 | |||
92 | private string[] GetAllPatchesList() | ||
93 | { | ||
94 | ArrayList patchList = new ArrayList(); | ||
95 | foreach(PatchInstallation patch in PatchInstallation.AllPatches) | ||
96 | { | ||
97 | if(!patchList.Contains(patch.PatchCode)) | ||
98 | { | ||
99 | patchList.Add(patch.PatchCode); | ||
100 | } | ||
101 | } | ||
102 | string[] patchArray = (string[]) patchList.ToArray(typeof(string)); | ||
103 | Array.Sort(patchArray, 0, patchArray.Length, StringComparer.Ordinal); | ||
104 | return patchArray; | ||
105 | } | ||
106 | |||
107 | private DataView GetAllPatchesData() | ||
108 | { | ||
109 | DataTable table = new DataTable("Patches"); | ||
110 | table.Locale = CultureInfo.InvariantCulture; | ||
111 | table.Columns.Add("PatchesPatchCode", typeof(string)); | ||
112 | |||
113 | foreach(string patchCode in GetAllPatchesList()) | ||
114 | { | ||
115 | table.Rows.Add(new object[] { patchCode }); | ||
116 | } | ||
117 | return new DataView(table, "", "PatchesPatchCode ASC", DataViewRowState.CurrentRows); | ||
118 | } | ||
119 | |||
120 | private DataView GetProductPatchData(string productCode) | ||
121 | { | ||
122 | DataTable table = new DataTable("ProductPatches"); | ||
123 | table.Locale = CultureInfo.InvariantCulture; | ||
124 | table.Columns.Add("ProductPatchesPatchCode", typeof(string)); | ||
125 | |||
126 | foreach(PatchInstallation patch in PatchInstallation.GetPatches(null, productCode, null, UserContexts.All, PatchStates.Applied)) | ||
127 | { | ||
128 | table.Rows.Add(new object[] { patch.PatchCode }); | ||
129 | } | ||
130 | return new DataView(table, "", "ProductPatchesPatchCode ASC", DataViewRowState.CurrentRows); | ||
131 | } | ||
132 | |||
133 | private DataView GetPatchData(string patchCode) | ||
134 | { | ||
135 | DataTable table = new DataTable("PatchProperties"); | ||
136 | table.Locale = CultureInfo.InvariantCulture; | ||
137 | table.Columns.Add("PatchPropertiesProperty", typeof(string)); | ||
138 | table.Columns.Add("PatchPropertiesValue", typeof(string)); | ||
139 | |||
140 | table.Rows.Add(new object[] { "PatchCode", patchCode }); | ||
141 | |||
142 | PatchInstallation patch = new PatchInstallation(patchCode, null); | ||
143 | |||
144 | string localPackage = null; | ||
145 | foreach(string property in new string[] | ||
146 | { | ||
147 | "InstallDate", | ||
148 | "LocalPackage", | ||
149 | "State", | ||
150 | "Transforms", | ||
151 | "Uninstallable", | ||
152 | }) | ||
153 | { | ||
154 | try | ||
155 | { | ||
156 | string value = patch[property]; | ||
157 | table.Rows.Add(new object[] { property, (value != null ? value : "") }); | ||
158 | if(property == "LocalPackage") localPackage = value; | ||
159 | } | ||
160 | catch(InstallerException iex) | ||
161 | { | ||
162 | table.Rows.Add(new object[] { property, iex.Message }); | ||
163 | } | ||
164 | catch(ArgumentException) { } | ||
165 | } | ||
166 | |||
167 | if(localPackage != null) | ||
168 | { | ||
169 | try | ||
170 | { | ||
171 | using(SummaryInfo patchSummaryInfo = new SummaryInfo(localPackage, false)) | ||
172 | { | ||
173 | table.Rows.Add(new object[] { "Title", patchSummaryInfo.Title }); | ||
174 | table.Rows.Add(new object[] { "Subject", patchSummaryInfo.Subject }); | ||
175 | table.Rows.Add(new object[] { "Author", patchSummaryInfo.Author }); | ||
176 | table.Rows.Add(new object[] { "Comments", patchSummaryInfo.Comments }); | ||
177 | table.Rows.Add(new object[] { "TargetProductCodes", patchSummaryInfo.Template }); | ||
178 | string obsoletedPatchCodes = patchSummaryInfo.RevisionNumber.Substring(patchSummaryInfo.RevisionNumber.IndexOf('}') + 1); | ||
179 | table.Rows.Add(new object[] { "ObsoletedPatchCodes", obsoletedPatchCodes }); | ||
180 | table.Rows.Add(new object[] { "TransformNames", patchSummaryInfo.LastSavedBy }); | ||
181 | } | ||
182 | } | ||
183 | catch(InstallerException) { } | ||
184 | catch(IOException) { } | ||
185 | catch(SecurityException) { } | ||
186 | } | ||
187 | return new DataView(table, "", "PatchPropertiesProperty ASC", DataViewRowState.CurrentRows); | ||
188 | } | ||
189 | |||
190 | private DataView GetPatchTargetData(string patchCode) | ||
191 | { | ||
192 | DataTable table = new DataTable("PatchTargets"); | ||
193 | table.Locale = CultureInfo.InvariantCulture; | ||
194 | table.Columns.Add("PatchTargetsProductName", typeof(string)); | ||
195 | table.Columns.Add("PatchTargetsProductCode", typeof(string)); | ||
196 | |||
197 | foreach (PatchInstallation patch in PatchInstallation.GetPatches(patchCode, null, null, UserContexts.All, PatchStates.Applied)) | ||
198 | { | ||
199 | if(patch.PatchCode == patchCode) | ||
200 | { | ||
201 | string productName = MsiUtils.GetProductName(patch.ProductCode); | ||
202 | table.Rows.Add(new object[] { productName, patch.ProductCode }); | ||
203 | } | ||
204 | } | ||
205 | return new DataView(table, "", "PatchTargetsProductName ASC", DataViewRowState.CurrentRows); | ||
206 | } | ||
207 | |||
208 | public string GetLink(string nodePath, DataRow row) | ||
209 | { | ||
210 | string[] path = nodePath.Split('\\'); | ||
211 | |||
212 | if(path.Length == 3 && path[0] == "Products" && path[2] == "Patches") | ||
213 | { | ||
214 | return String.Format(@"Patches\{0}", row["ProductPatchesPatchCode"]); | ||
215 | } | ||
216 | else if(path.Length == 1 && path[0] == "Patches") | ||
217 | { | ||
218 | return String.Format(@"Patches\{0}", row["PatchesPatchCode"]); | ||
219 | } | ||
220 | else if(path.Length == 3 && path[0] == "Patches" && path[2] == "Patched Products") | ||
221 | { | ||
222 | return String.Format(@"Products\{0}", MsiUtils.GetProductCode((string) row["PatchTargetsProductCode"])); | ||
223 | } | ||
224 | return null; | ||
225 | } | ||
226 | } | ||
227 | } | ||