aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs')
-rw-r--r--src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs121
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
3namespace 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}