diff options
author | Rob Mensching <rob@firegiant.com> | 2017-10-14 16:12:07 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2017-10-14 16:12:07 -0700 |
commit | dbde9e7104b907bbbaea17e21247d8cafc8b3a4c (patch) | |
tree | 0f5fbbb6fe12c6b2e5e622a0e18ce4c5b4eb2b96 /src/WixToolset.Core.WindowsInstaller/Differ.cs | |
parent | fbf986eb97f68396797a89fc7d40dec07b775440 (diff) | |
download | wix-dbde9e7104b907bbbaea17e21247d8cafc8b3a4c.tar.gz wix-dbde9e7104b907bbbaea17e21247d8cafc8b3a4c.tar.bz2 wix-dbde9e7104b907bbbaea17e21247d8cafc8b3a4c.zip |
Massive refactoring to introduce the concept of IBackend
Diffstat (limited to 'src/WixToolset.Core.WindowsInstaller/Differ.cs')
-rw-r--r-- | src/WixToolset.Core.WindowsInstaller/Differ.cs | 611 |
1 files changed, 611 insertions, 0 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/Differ.cs b/src/WixToolset.Core.WindowsInstaller/Differ.cs new file mode 100644 index 00000000..bdd06d32 --- /dev/null +++ b/src/WixToolset.Core.WindowsInstaller/Differ.cs | |||
@@ -0,0 +1,611 @@ | |||
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 | namespace WixToolset | ||
4 | { | ||
5 | using System; | ||
6 | using System.Collections; | ||
7 | using System.Collections.Generic; | ||
8 | using System.Globalization; | ||
9 | using WixToolset.Core; | ||
10 | using WixToolset.Data; | ||
11 | using WixToolset.Data.Rows; | ||
12 | using WixToolset.Extensibility; | ||
13 | using WixToolset.Msi; | ||
14 | |||
15 | /// <summary> | ||
16 | /// Creates a transform by diffing two outputs. | ||
17 | /// </summary> | ||
18 | public sealed class Differ : IMessageHandler | ||
19 | { | ||
20 | private List<IInspectorExtension> inspectorExtensions; | ||
21 | private bool showPedanticMessages; | ||
22 | private bool suppressKeepingSpecialRows; | ||
23 | private bool preserveUnchangedRows; | ||
24 | private const char sectionDelimiter = '/'; | ||
25 | private SummaryInformationStreams transformSummaryInfo; | ||
26 | |||
27 | /// <summary> | ||
28 | /// Instantiates a new Differ class. | ||
29 | /// </summary> | ||
30 | public Differ() | ||
31 | { | ||
32 | this.inspectorExtensions = new List<IInspectorExtension>(); | ||
33 | } | ||
34 | |||
35 | /// <summary> | ||
36 | /// Gets or sets the option to show pedantic messages. | ||
37 | /// </summary> | ||
38 | /// <value>The option to show pedantic messages.</value> | ||
39 | public bool ShowPedanticMessages | ||
40 | { | ||
41 | get { return this.showPedanticMessages; } | ||
42 | set { this.showPedanticMessages = value; } | ||
43 | } | ||
44 | |||
45 | /// <summary> | ||
46 | /// Gets or sets the option to suppress keeping special rows. | ||
47 | /// </summary> | ||
48 | /// <value>The option to suppress keeping special rows.</value> | ||
49 | public bool SuppressKeepingSpecialRows | ||
50 | { | ||
51 | get { return this.suppressKeepingSpecialRows; } | ||
52 | set { this.suppressKeepingSpecialRows = value; } | ||
53 | } | ||
54 | |||
55 | /// <summary> | ||
56 | /// Gets or sets the flag to determine if all rows, even unchanged ones will be persisted in the output. | ||
57 | /// </summary> | ||
58 | /// <value>The option to keep all rows including unchanged rows.</value> | ||
59 | public bool PreserveUnchangedRows | ||
60 | { | ||
61 | get { return this.preserveUnchangedRows; } | ||
62 | set { this.preserveUnchangedRows = value; } | ||
63 | } | ||
64 | |||
65 | /// <summary> | ||
66 | /// Adds an extension. | ||
67 | /// </summary> | ||
68 | /// <param name="extension">The extension to add.</param> | ||
69 | public void AddExtension(IInspectorExtension extension) | ||
70 | { | ||
71 | this.inspectorExtensions.Add(extension); | ||
72 | } | ||
73 | |||
74 | /// <summary> | ||
75 | /// Creates a transform by diffing two outputs. | ||
76 | /// </summary> | ||
77 | /// <param name="targetOutput">The target output.</param> | ||
78 | /// <param name="updatedOutput">The updated output.</param> | ||
79 | /// <returns>The transform.</returns> | ||
80 | public Output Diff(Output targetOutput, Output updatedOutput) | ||
81 | { | ||
82 | return Diff(targetOutput, updatedOutput, 0); | ||
83 | } | ||
84 | |||
85 | /// <summary> | ||
86 | /// Creates a transform by diffing two outputs. | ||
87 | /// </summary> | ||
88 | /// <param name="targetOutput">The target output.</param> | ||
89 | /// <param name="updatedOutput">The updated output.</param> | ||
90 | /// <param name="validationFlags"></param> | ||
91 | /// <returns>The transform.</returns> | ||
92 | public Output Diff(Output targetOutput, Output updatedOutput, TransformFlags validationFlags) | ||
93 | { | ||
94 | Output transform = new Output(null); | ||
95 | transform.Type = OutputType.Transform; | ||
96 | transform.Codepage = updatedOutput.Codepage; | ||
97 | this.transformSummaryInfo = new SummaryInformationStreams(); | ||
98 | |||
99 | // compare the codepages | ||
100 | if (targetOutput.Codepage != updatedOutput.Codepage && 0 == (TransformFlags.ErrorChangeCodePage & validationFlags)) | ||
101 | { | ||
102 | this.OnMessage(WixErrors.OutputCodepageMismatch(targetOutput.SourceLineNumbers, targetOutput.Codepage, updatedOutput.Codepage)); | ||
103 | if (null != updatedOutput.SourceLineNumbers) | ||
104 | { | ||
105 | this.OnMessage(WixErrors.OutputCodepageMismatch2(updatedOutput.SourceLineNumbers)); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | // compare the output types | ||
110 | if (targetOutput.Type != updatedOutput.Type) | ||
111 | { | ||
112 | throw new WixException(WixErrors.OutputTypeMismatch(targetOutput.SourceLineNumbers, targetOutput.Type.ToString(), updatedOutput.Type.ToString())); | ||
113 | } | ||
114 | |||
115 | // compare the contents of the tables | ||
116 | foreach (Table targetTable in targetOutput.Tables) | ||
117 | { | ||
118 | Table updatedTable = updatedOutput.Tables[targetTable.Name]; | ||
119 | TableOperation operation = TableOperation.None; | ||
120 | |||
121 | List<Row> rows = this.CompareTables(targetOutput, targetTable, updatedTable, out operation); | ||
122 | |||
123 | if (TableOperation.Drop == operation) | ||
124 | { | ||
125 | Table droppedTable = transform.EnsureTable(targetTable.Definition); | ||
126 | droppedTable.Operation = TableOperation.Drop; | ||
127 | } | ||
128 | else if (TableOperation.None == operation) | ||
129 | { | ||
130 | Table modified = transform.EnsureTable(updatedTable.Definition); | ||
131 | rows.ForEach(r => modified.Rows.Add(r)); | ||
132 | } | ||
133 | } | ||
134 | |||
135 | // added tables | ||
136 | foreach (Table updatedTable in updatedOutput.Tables) | ||
137 | { | ||
138 | if (null == targetOutput.Tables[updatedTable.Name]) | ||
139 | { | ||
140 | Table addedTable = transform.EnsureTable(updatedTable.Definition); | ||
141 | addedTable.Operation = TableOperation.Add; | ||
142 | |||
143 | foreach (Row updatedRow in updatedTable.Rows) | ||
144 | { | ||
145 | updatedRow.Operation = RowOperation.Add; | ||
146 | updatedRow.SectionId = sectionDelimiter + updatedRow.SectionId; | ||
147 | addedTable.Rows.Add(updatedRow); | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | |||
152 | // set summary information properties | ||
153 | if (!this.suppressKeepingSpecialRows) | ||
154 | { | ||
155 | Table summaryInfoTable = transform.Tables["_SummaryInformation"]; | ||
156 | this.UpdateTransformSummaryInformationTable(summaryInfoTable, validationFlags); | ||
157 | } | ||
158 | |||
159 | return transform; | ||
160 | } | ||
161 | |||
162 | /// <summary> | ||
163 | /// Sends a message to the message delegate if there is one. | ||
164 | /// </summary> | ||
165 | /// <param name="mea">Message event arguments.</param> | ||
166 | public void OnMessage(MessageEventArgs e) | ||
167 | { | ||
168 | Messaging.Instance.OnMessage(e); | ||
169 | } | ||
170 | |||
171 | /// <summary> | ||
172 | /// Add a row to the <paramref name="index"/> using the primary key. | ||
173 | /// </summary> | ||
174 | /// <param name="index">The indexed rows.</param> | ||
175 | /// <param name="row">The row to index.</param> | ||
176 | private void AddIndexedRow(IDictionary index, Row row) | ||
177 | { | ||
178 | string primaryKey = row.GetPrimaryKey('/'); | ||
179 | if (null != primaryKey) | ||
180 | { | ||
181 | // Overriding WixActionRows have a primary key defined and take precedence in the index. | ||
182 | if (row is WixActionRow) | ||
183 | { | ||
184 | WixActionRow currentRow = (WixActionRow)row; | ||
185 | if (index.Contains(primaryKey)) | ||
186 | { | ||
187 | // If the current row is not overridable, see if the indexed row is. | ||
188 | if (!currentRow.Overridable) | ||
189 | { | ||
190 | WixActionRow indexedRow = index[primaryKey] as WixActionRow; | ||
191 | if (null != indexedRow && indexedRow.Overridable) | ||
192 | { | ||
193 | // The indexed key is overridable and should be replaced | ||
194 | // (not removed and re-added which results in two Array.Copy | ||
195 | // operations for SortedList, or may be re-hashing in other | ||
196 | // implementations of IDictionary). | ||
197 | index[primaryKey] = currentRow; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | // If we got this far, the row does not need to be indexed. | ||
202 | return; | ||
203 | } | ||
204 | } | ||
205 | |||
206 | // Nothing else should be added more than once. | ||
207 | if (!index.Contains(primaryKey)) | ||
208 | { | ||
209 | index.Add(primaryKey, row); | ||
210 | } | ||
211 | else if (this.showPedanticMessages) | ||
212 | { | ||
213 | this.OnMessage(WixWarnings.DuplicatePrimaryKey(row.SourceLineNumbers, primaryKey, row.Table.Name)); | ||
214 | } | ||
215 | } | ||
216 | else // use the string representation of the row as its primary key (it may not be unique) | ||
217 | { | ||
218 | // this is provided for compatibility with unreal tables with no primary key | ||
219 | // all real tables must specify at least one column as the primary key | ||
220 | primaryKey = row.ToString(); | ||
221 | index[primaryKey] = row; | ||
222 | } | ||
223 | } | ||
224 | |||
225 | private Row CompareRows(Table targetTable, Row targetRow, Row updatedRow, out RowOperation operation, out bool keepRow) | ||
226 | { | ||
227 | Row comparedRow = null; | ||
228 | keepRow = false; | ||
229 | operation = RowOperation.None; | ||
230 | |||
231 | if (null == targetRow ^ null == updatedRow) | ||
232 | { | ||
233 | if (null == targetRow) | ||
234 | { | ||
235 | operation = updatedRow.Operation = RowOperation.Add; | ||
236 | comparedRow = updatedRow; | ||
237 | } | ||
238 | else if (null == updatedRow) | ||
239 | { | ||
240 | operation = targetRow.Operation = RowOperation.Delete; | ||
241 | targetRow.SectionId = targetRow.SectionId + sectionDelimiter; | ||
242 | comparedRow = targetRow; | ||
243 | keepRow = true; | ||
244 | } | ||
245 | } | ||
246 | else // possibly modified | ||
247 | { | ||
248 | updatedRow.Operation = RowOperation.None; | ||
249 | if (!this.suppressKeepingSpecialRows && "_SummaryInformation" == targetTable.Name) | ||
250 | { | ||
251 | // ignore rows that shouldn't be in a transform | ||
252 | if (Enum.IsDefined(typeof(SummaryInformation.Transform), (int)updatedRow[0])) | ||
253 | { | ||
254 | updatedRow.SectionId = targetRow.SectionId + sectionDelimiter + updatedRow.SectionId; | ||
255 | comparedRow = updatedRow; | ||
256 | keepRow = true; | ||
257 | operation = RowOperation.Modify; | ||
258 | } | ||
259 | } | ||
260 | else | ||
261 | { | ||
262 | if (this.preserveUnchangedRows) | ||
263 | { | ||
264 | keepRow = true; | ||
265 | } | ||
266 | |||
267 | for (int i = 0; i < updatedRow.Fields.Length; i++) | ||
268 | { | ||
269 | ColumnDefinition columnDefinition = updatedRow.Fields[i].Column; | ||
270 | |||
271 | if (!columnDefinition.PrimaryKey) | ||
272 | { | ||
273 | bool modified = false; | ||
274 | |||
275 | if (i >= targetRow.Fields.Length) | ||
276 | { | ||
277 | columnDefinition.Added = true; | ||
278 | modified = true; | ||
279 | } | ||
280 | else if (ColumnType.Number == columnDefinition.Type && !columnDefinition.IsLocalizable) | ||
281 | { | ||
282 | if (null == targetRow[i] ^ null == updatedRow[i]) | ||
283 | { | ||
284 | modified = true; | ||
285 | } | ||
286 | else if (null != targetRow[i] && null != updatedRow[i]) | ||
287 | { | ||
288 | modified = ((int)targetRow[i] != (int)updatedRow[i]); | ||
289 | } | ||
290 | } | ||
291 | else if (ColumnType.Preserved == columnDefinition.Type) | ||
292 | { | ||
293 | updatedRow.Fields[i].PreviousData = (string)targetRow.Fields[i].Data; | ||
294 | |||
295 | // keep rows containing preserved fields so the historical data is available to the binder | ||
296 | keepRow = !this.suppressKeepingSpecialRows; | ||
297 | } | ||
298 | else if (ColumnType.Object == columnDefinition.Type) | ||
299 | { | ||
300 | ObjectField targetObjectField = (ObjectField)targetRow.Fields[i]; | ||
301 | ObjectField updatedObjectField = (ObjectField)updatedRow.Fields[i]; | ||
302 | |||
303 | updatedObjectField.PreviousEmbeddedFileIndex = targetObjectField.EmbeddedFileIndex; | ||
304 | updatedObjectField.PreviousBaseUri = targetObjectField.BaseUri; | ||
305 | |||
306 | // always keep a copy of the previous data even if they are identical | ||
307 | // This makes diff.wixmst clean and easier to control patch logic | ||
308 | updatedObjectField.PreviousData = (string)targetObjectField.Data; | ||
309 | |||
310 | // always remember the unresolved data for target build | ||
311 | updatedObjectField.UnresolvedPreviousData = (string)targetObjectField.UnresolvedData; | ||
312 | |||
313 | // keep rows containing object fields so the files can be compared in the binder | ||
314 | keepRow = !this.suppressKeepingSpecialRows; | ||
315 | } | ||
316 | else | ||
317 | { | ||
318 | modified = ((string)targetRow[i] != (string)updatedRow[i]); | ||
319 | } | ||
320 | |||
321 | if (modified) | ||
322 | { | ||
323 | if (null != updatedRow.Fields[i].PreviousData) | ||
324 | { | ||
325 | updatedRow.Fields[i].PreviousData = targetRow.Fields[i].Data.ToString(); | ||
326 | } | ||
327 | |||
328 | updatedRow.Fields[i].Modified = true; | ||
329 | operation = updatedRow.Operation = RowOperation.Modify; | ||
330 | keepRow = true; | ||
331 | } | ||
332 | } | ||
333 | } | ||
334 | |||
335 | if (keepRow) | ||
336 | { | ||
337 | comparedRow = updatedRow; | ||
338 | comparedRow.SectionId = targetRow.SectionId + sectionDelimiter + updatedRow.SectionId; | ||
339 | } | ||
340 | } | ||
341 | } | ||
342 | |||
343 | return comparedRow; | ||
344 | } | ||
345 | |||
346 | private List<Row> CompareTables(Output targetOutput, Table targetTable, Table updatedTable, out TableOperation operation) | ||
347 | { | ||
348 | List<Row> rows = new List<Row>(); | ||
349 | operation = TableOperation.None; | ||
350 | |||
351 | // dropped tables | ||
352 | if (null == updatedTable ^ null == targetTable) | ||
353 | { | ||
354 | if (null == targetTable) | ||
355 | { | ||
356 | operation = TableOperation.Add; | ||
357 | rows.AddRange(updatedTable.Rows); | ||
358 | } | ||
359 | else if (null == updatedTable) | ||
360 | { | ||
361 | operation = TableOperation.Drop; | ||
362 | } | ||
363 | } | ||
364 | else // possibly modified tables | ||
365 | { | ||
366 | SortedList updatedPrimaryKeys = new SortedList(); | ||
367 | SortedList targetPrimaryKeys = new SortedList(); | ||
368 | |||
369 | // compare the table definitions | ||
370 | if (0 != targetTable.Definition.CompareTo(updatedTable.Definition)) | ||
371 | { | ||
372 | // continue to the next table; may be more mismatches | ||
373 | this.OnMessage(WixErrors.DatabaseSchemaMismatch(targetOutput.SourceLineNumbers, targetTable.Name)); | ||
374 | } | ||
375 | else | ||
376 | { | ||
377 | this.IndexPrimaryKeys(targetTable, targetPrimaryKeys, updatedTable, updatedPrimaryKeys); | ||
378 | |||
379 | // diff the target and updated rows | ||
380 | foreach (DictionaryEntry targetPrimaryKeyEntry in targetPrimaryKeys) | ||
381 | { | ||
382 | string targetPrimaryKey = (string)targetPrimaryKeyEntry.Key; | ||
383 | bool keepRow = false; | ||
384 | RowOperation rowOperation = RowOperation.None; | ||
385 | |||
386 | Row compared = this.CompareRows(targetTable, targetPrimaryKeyEntry.Value as Row, updatedPrimaryKeys[targetPrimaryKey] as Row, out rowOperation, out keepRow); | ||
387 | |||
388 | if (keepRow) | ||
389 | { | ||
390 | rows.Add(compared); | ||
391 | } | ||
392 | } | ||
393 | |||
394 | // find the inserted rows | ||
395 | foreach (DictionaryEntry updatedPrimaryKeyEntry in updatedPrimaryKeys) | ||
396 | { | ||
397 | string updatedPrimaryKey = (string)updatedPrimaryKeyEntry.Key; | ||
398 | |||
399 | if (!targetPrimaryKeys.Contains(updatedPrimaryKey)) | ||
400 | { | ||
401 | Row updatedRow = (Row)updatedPrimaryKeyEntry.Value; | ||
402 | |||
403 | updatedRow.Operation = RowOperation.Add; | ||
404 | updatedRow.SectionId = sectionDelimiter + updatedRow.SectionId; | ||
405 | rows.Add(updatedRow); | ||
406 | } | ||
407 | } | ||
408 | } | ||
409 | } | ||
410 | |||
411 | return rows; | ||
412 | } | ||
413 | |||
414 | private void IndexPrimaryKeys(Table targetTable, SortedList targetPrimaryKeys, Table updatedTable, SortedList updatedPrimaryKeys) | ||
415 | { | ||
416 | // index the target rows | ||
417 | foreach (Row row in targetTable.Rows) | ||
418 | { | ||
419 | this.AddIndexedRow(targetPrimaryKeys, row); | ||
420 | |||
421 | if ("Property" == targetTable.Name) | ||
422 | { | ||
423 | if ("ProductCode" == (string)row[0]) | ||
424 | { | ||
425 | this.transformSummaryInfo.TargetProductCode = (string)row[1]; | ||
426 | if ("*" == this.transformSummaryInfo.TargetProductCode) | ||
427 | { | ||
428 | this.OnMessage(WixErrors.ProductCodeInvalidForTransform(row.SourceLineNumbers)); | ||
429 | } | ||
430 | } | ||
431 | else if ("ProductVersion" == (string)row[0]) | ||
432 | { | ||
433 | this.transformSummaryInfo.TargetProductVersion = (string)row[1]; | ||
434 | } | ||
435 | else if ("UpgradeCode" == (string)row[0]) | ||
436 | { | ||
437 | this.transformSummaryInfo.TargetUpgradeCode = (string)row[1]; | ||
438 | } | ||
439 | } | ||
440 | else if ("_SummaryInformation" == targetTable.Name) | ||
441 | { | ||
442 | if (1 == (int)row[0]) // PID_CODEPAGE | ||
443 | { | ||
444 | this.transformSummaryInfo.TargetSummaryInfoCodepage = (string)row[1]; | ||
445 | } | ||
446 | else if (7 == (int)row[0]) // PID_TEMPLATE | ||
447 | { | ||
448 | this.transformSummaryInfo.TargetPlatformAndLanguage = (string)row[1]; | ||
449 | } | ||
450 | else if (14 == (int)row[0]) // PID_PAGECOUNT | ||
451 | { | ||
452 | this.transformSummaryInfo.TargetMinimumVersion = (string)row[1]; | ||
453 | } | ||
454 | } | ||
455 | } | ||
456 | |||
457 | // index the updated rows | ||
458 | foreach (Row row in updatedTable.Rows) | ||
459 | { | ||
460 | this.AddIndexedRow(updatedPrimaryKeys, row); | ||
461 | |||
462 | if ("Property" == updatedTable.Name) | ||
463 | { | ||
464 | if ("ProductCode" == (string)row[0]) | ||
465 | { | ||
466 | this.transformSummaryInfo.UpdatedProductCode = (string)row[1]; | ||
467 | if ("*" == this.transformSummaryInfo.UpdatedProductCode) | ||
468 | { | ||
469 | this.OnMessage(WixErrors.ProductCodeInvalidForTransform(row.SourceLineNumbers)); | ||
470 | } | ||
471 | } | ||
472 | else if ("ProductVersion" == (string)row[0]) | ||
473 | { | ||
474 | this.transformSummaryInfo.UpdatedProductVersion = (string)row[1]; | ||
475 | } | ||
476 | } | ||
477 | else if ("_SummaryInformation" == updatedTable.Name) | ||
478 | { | ||
479 | if (1 == (int)row[0]) // PID_CODEPAGE | ||
480 | { | ||
481 | this.transformSummaryInfo.UpdatedSummaryInfoCodepage = (string)row[1]; | ||
482 | } | ||
483 | else if (7 == (int)row[0]) // PID_TEMPLATE | ||
484 | { | ||
485 | this.transformSummaryInfo.UpdatedPlatformAndLanguage = (string)row[1]; | ||
486 | } | ||
487 | else if (14 == (int)row[0]) // PID_PAGECOUNT | ||
488 | { | ||
489 | this.transformSummaryInfo.UpdatedMinimumVersion = (string)row[1]; | ||
490 | } | ||
491 | } | ||
492 | } | ||
493 | } | ||
494 | |||
495 | private void UpdateTransformSummaryInformationTable(Table summaryInfoTable, TransformFlags validationFlags) | ||
496 | { | ||
497 | // calculate the minimum version of MSI required to process the transform | ||
498 | int targetMin; | ||
499 | int updatedMin; | ||
500 | int minimumVersion = 100; | ||
501 | |||
502 | if (Int32.TryParse(this.transformSummaryInfo.TargetMinimumVersion, out targetMin) && Int32.TryParse(this.transformSummaryInfo.UpdatedMinimumVersion, out updatedMin)) | ||
503 | { | ||
504 | minimumVersion = Math.Max(targetMin, updatedMin); | ||
505 | } | ||
506 | |||
507 | Hashtable summaryRows = new Hashtable(summaryInfoTable.Rows.Count); | ||
508 | foreach (Row row in summaryInfoTable.Rows) | ||
509 | { | ||
510 | summaryRows[row[0]] = row; | ||
511 | |||
512 | if ((int)SummaryInformation.Transform.CodePage == (int)row[0]) | ||
513 | { | ||
514 | row.Fields[1].Data = this.transformSummaryInfo.UpdatedSummaryInfoCodepage; | ||
515 | row.Fields[1].PreviousData = this.transformSummaryInfo.TargetSummaryInfoCodepage; | ||
516 | } | ||
517 | else if ((int)SummaryInformation.Transform.TargetPlatformAndLanguage == (int)row[0]) | ||
518 | { | ||
519 | row[1] = this.transformSummaryInfo.TargetPlatformAndLanguage; | ||
520 | } | ||
521 | else if ((int)SummaryInformation.Transform.UpdatedPlatformAndLanguage == (int)row[0]) | ||
522 | { | ||
523 | row[1] = this.transformSummaryInfo.UpdatedPlatformAndLanguage; | ||
524 | } | ||
525 | else if ((int)SummaryInformation.Transform.ProductCodes == (int)row[0]) | ||
526 | { | ||
527 | row[1] = String.Concat(this.transformSummaryInfo.TargetProductCode, this.transformSummaryInfo.TargetProductVersion, ';', this.transformSummaryInfo.UpdatedProductCode, this.transformSummaryInfo.UpdatedProductVersion, ';', this.transformSummaryInfo.TargetUpgradeCode); | ||
528 | } | ||
529 | else if ((int)SummaryInformation.Transform.InstallerRequirement == (int)row[0]) | ||
530 | { | ||
531 | row[1] = minimumVersion.ToString(CultureInfo.InvariantCulture); | ||
532 | } | ||
533 | else if ((int)SummaryInformation.Transform.Security == (int)row[0]) | ||
534 | { | ||
535 | row[1] = "4"; | ||
536 | } | ||
537 | } | ||
538 | |||
539 | if (!summaryRows.Contains((int)SummaryInformation.Transform.TargetPlatformAndLanguage)) | ||
540 | { | ||
541 | Row summaryRow = summaryInfoTable.CreateRow(null); | ||
542 | summaryRow[0] = (int)SummaryInformation.Transform.TargetPlatformAndLanguage; | ||
543 | summaryRow[1] = this.transformSummaryInfo.TargetPlatformAndLanguage; | ||
544 | } | ||
545 | |||
546 | if (!summaryRows.Contains((int)SummaryInformation.Transform.UpdatedPlatformAndLanguage)) | ||
547 | { | ||
548 | Row summaryRow = summaryInfoTable.CreateRow(null); | ||
549 | summaryRow[0] = (int)SummaryInformation.Transform.UpdatedPlatformAndLanguage; | ||
550 | summaryRow[1] = this.transformSummaryInfo.UpdatedPlatformAndLanguage; | ||
551 | } | ||
552 | |||
553 | if (!summaryRows.Contains((int)SummaryInformation.Transform.ValidationFlags)) | ||
554 | { | ||
555 | Row summaryRow = summaryInfoTable.CreateRow(null); | ||
556 | summaryRow[0] = (int)SummaryInformation.Transform.ValidationFlags; | ||
557 | summaryRow[1] = ((int)validationFlags).ToString(CultureInfo.InvariantCulture); | ||
558 | } | ||
559 | |||
560 | if (!summaryRows.Contains((int)SummaryInformation.Transform.InstallerRequirement)) | ||
561 | { | ||
562 | Row summaryRow = summaryInfoTable.CreateRow(null); | ||
563 | summaryRow[0] = (int)SummaryInformation.Transform.InstallerRequirement; | ||
564 | summaryRow[1] = minimumVersion.ToString(CultureInfo.InvariantCulture); | ||
565 | } | ||
566 | |||
567 | if (!summaryRows.Contains((int)SummaryInformation.Transform.Security)) | ||
568 | { | ||
569 | Row summaryRow = summaryInfoTable.CreateRow(null); | ||
570 | summaryRow[0] = (int)SummaryInformation.Transform.Security; | ||
571 | summaryRow[1] = "4"; | ||
572 | } | ||
573 | } | ||
574 | |||
575 | private class SummaryInformationStreams | ||
576 | { | ||
577 | public string TargetSummaryInfoCodepage | ||
578 | { get; set; } | ||
579 | |||
580 | public string TargetPlatformAndLanguage | ||
581 | { get; set; } | ||
582 | |||
583 | public string TargetProductCode | ||
584 | { get; set; } | ||
585 | |||
586 | public string TargetProductVersion | ||
587 | { get; set; } | ||
588 | |||
589 | public string TargetUpgradeCode | ||
590 | { get; set; } | ||
591 | |||
592 | public string TargetMinimumVersion | ||
593 | { get; set; } | ||
594 | |||
595 | public string UpdatedSummaryInfoCodepage | ||
596 | { get; set; } | ||
597 | |||
598 | public string UpdatedPlatformAndLanguage | ||
599 | { get; set; } | ||
600 | |||
601 | public string UpdatedProductCode | ||
602 | { get; set; } | ||
603 | |||
604 | public string UpdatedProductVersion | ||
605 | { get; set; } | ||
606 | |||
607 | public string UpdatedMinimumVersion | ||
608 | { get; set; } | ||
609 | } | ||
610 | } | ||
611 | } | ||