diff options
Diffstat (limited to 'src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs')
-rw-r--r-- | src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs b/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs new file mode 100644 index 00000000..4ffe9e82 --- /dev/null +++ b/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs | |||
@@ -0,0 +1,121 @@ | |||
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.Bind | ||
4 | { | ||
5 | using System; | ||
6 | using System.Collections.Generic; | ||
7 | using System.Globalization; | ||
8 | using System.Linq; | ||
9 | using System.Text; | ||
10 | using WixToolset.Data; | ||
11 | |||
12 | /// <summary> | ||
13 | /// Resolves the fields which had variables that needed to be resolved after the file information | ||
14 | /// was loaded. | ||
15 | /// </summary> | ||
16 | internal class ResolveDelayedFieldsCommand : ICommand | ||
17 | { | ||
18 | public OutputType OutputType { private get; set;} | ||
19 | |||
20 | public IEnumerable<DelayedField> DelayedFields { private get; set;} | ||
21 | |||
22 | public IDictionary<string, string> VariableCache { private get; set; } | ||
23 | |||
24 | public string ModularizationGuid { private get; set; } | ||
25 | |||
26 | /// <param name="output">Internal representation of the msi database to operate upon.</param> | ||
27 | /// <param name="delayedFields">The fields which had resolution delayed.</param> | ||
28 | /// <param name="variableCache">The file information to use when resolving variables.</param> | ||
29 | /// <param name="modularizationGuid">The modularization guid (used in case of a merge module).</param> | ||
30 | public void Execute() | ||
31 | { | ||
32 | List<DelayedField> deferredFields = new List<DelayedField>(); | ||
33 | |||
34 | foreach (DelayedField delayedField in this.DelayedFields) | ||
35 | { | ||
36 | try | ||
37 | { | ||
38 | Row propertyRow = delayedField.Row; | ||
39 | |||
40 | // process properties first in case they refer to other binder variables | ||
41 | if ("Property" == propertyRow.Table.Name) | ||
42 | { | ||
43 | string value = WixVariableResolver.ResolveDelayedVariables(propertyRow.SourceLineNumbers, (string)delayedField.Field.Data, this.VariableCache); | ||
44 | |||
45 | // update the variable cache with the new value | ||
46 | string key = String.Concat("property.", BindDatabaseCommand.Demodularize(this.OutputType, this.ModularizationGuid, (string)propertyRow[0])); | ||
47 | this.VariableCache[key] = value; | ||
48 | |||
49 | // update the field data | ||
50 | delayedField.Field.Data = value; | ||
51 | } | ||
52 | else | ||
53 | { | ||
54 | deferredFields.Add(delayedField); | ||
55 | } | ||
56 | } | ||
57 | catch (WixException we) | ||
58 | { | ||
59 | Messaging.Instance.OnMessage(we.Error); | ||
60 | continue; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | // add specialization for ProductVersion fields | ||
65 | string keyProductVersion = "property.ProductVersion"; | ||
66 | if (this.VariableCache.ContainsKey(keyProductVersion)) | ||
67 | { | ||
68 | string value = this.VariableCache[keyProductVersion]; | ||
69 | Version productVersion = null; | ||
70 | |||
71 | try | ||
72 | { | ||
73 | productVersion = new Version(value); | ||
74 | |||
75 | // Don't add the variable if it already exists (developer defined a property with the same name). | ||
76 | string fieldKey = String.Concat(keyProductVersion, ".Major"); | ||
77 | if (!this.VariableCache.ContainsKey(fieldKey)) | ||
78 | { | ||
79 | this.VariableCache[fieldKey] = productVersion.Major.ToString(CultureInfo.InvariantCulture); | ||
80 | } | ||
81 | |||
82 | fieldKey = String.Concat(keyProductVersion, ".Minor"); | ||
83 | if (!this.VariableCache.ContainsKey(fieldKey)) | ||
84 | { | ||
85 | this.VariableCache[fieldKey] = productVersion.Minor.ToString(CultureInfo.InvariantCulture); | ||
86 | } | ||
87 | |||
88 | fieldKey = String.Concat(keyProductVersion, ".Build"); | ||
89 | if (!this.VariableCache.ContainsKey(fieldKey)) | ||
90 | { | ||
91 | this.VariableCache[fieldKey] = productVersion.Build.ToString(CultureInfo.InvariantCulture); | ||
92 | } | ||
93 | |||
94 | fieldKey = String.Concat(keyProductVersion, ".Revision"); | ||
95 | if (!this.VariableCache.ContainsKey(fieldKey)) | ||
96 | { | ||
97 | this.VariableCache[fieldKey] = productVersion.Revision.ToString(CultureInfo.InvariantCulture); | ||
98 | } | ||
99 | } | ||
100 | catch | ||
101 | { | ||
102 | // Ignore the error introduced by new behavior. | ||
103 | } | ||
104 | } | ||
105 | |||
106 | // process the remaining fields in case they refer to property binder variables | ||
107 | foreach (DelayedField delayedField in deferredFields) | ||
108 | { | ||
109 | try | ||
110 | { | ||
111 | delayedField.Field.Data = WixVariableResolver.ResolveDelayedVariables(delayedField.Row.SourceLineNumbers, (string)delayedField.Field.Data, this.VariableCache); | ||
112 | } | ||
113 | catch (WixException we) | ||
114 | { | ||
115 | Messaging.Instance.OnMessage(we.Error); | ||
116 | continue; | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | } | ||