@joebigelow / wix / commits / 752301ba

Fix custom tables, small fixes in linker and update latest Data

Rob Mensching committed Oct 23, 2019 at 12:53 UTC 752301ba571020717862d2232e3fad585de6a39a
13 files changed +427 -476
src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+20 -14
@@ -32,8 +32,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
32
33 this.PathResolver = this.ServiceProvider.GetService<IPathResolver>();
34
35 - this.TableDefinitions = WindowsInstallerStandardInternal.GetTableDefinitions();
36 -
35 this.CabbingThreadCount = context.CabbingThreadCount;
36 this.CabCachePath = context.CabCachePath;
37 this.Codepage = context.Codepage;
@@ -86,8 +84,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
84
85 private bool SuppressLayout { get; }
86
89 - private TableDefinitionCollection TableDefinitions { get; }
90 -
87 private string IntermediateFolder { get; }
88
89 private Validator Validator { get; }
@@ -111,6 +107,14 @@ namespace WixToolset.Core.WindowsInstaller.Bind
107 // If there are any fields to resolve later, create the cache to populate during bind.
108 var variableCache = this.DelayedFields.Any() ? new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase) : null;
109
110 + TableDefinitionCollection tableDefinitions;
111 + {
112 + var command = new LoadTableDefinitionsCommand(section);
113 + command.Execute();
114 +
115 + tableDefinitions = command.TableDefinitions;
116 + }
117 +
118 // Process the summary information table before the other tables.
119 bool compressed;
120 bool longNames;
@@ -231,7 +235,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
235 command.FileFacades = fileFacades;
236 command.UpdateFileFacades = fileFacades.Where(f => !f.FromModule);
237 command.OverwriteHash = true;
234 - command.TableDefinitions = this.TableDefinitions;
238 + command.TableDefinitions = tableDefinitions;
239 command.VariableCache = variableCache;
240 command.Execute();
241 }
@@ -308,7 +312,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
312 // Time to create the output object. Try to put as much above here as possible, updating the IR is better.
313 Output output;
314 {
311 - var command = new CreateOutputFromIRCommand(section, this.TableDefinitions, this.BackendExtensions);
315 + var command = new CreateOutputFromIRCommand(this.Messaging, section, tableDefinitions, this.BackendExtensions);
316 command.Execute();
317
318 output = command.Output;
@@ -402,7 +406,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
406 command.Compressed = compressed;
407 command.FileRowsByCabinet = filesByCabinetMedia;
408 command.ResolveMedia = this.ResolveMedia;
405 - command.TableDefinitions = this.TableDefinitions;
409 + command.TableDefinitions = tableDefinitions;
410 command.TempFilesLocation = this.IntermediateFolder;
411 command.Execute();
412
@@ -429,11 +433,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind
433 // Generate database file.
434 this.Messaging.Write(VerboseMessages.GeneratingDatabase());
435
432 - var trackMsi = this.BackendHelper.TrackFile(this.OutputPath, TrackedFileType.Final);
433 - trackedFiles.Add(trackMsi);
436 + {
437 + var trackMsi = this.BackendHelper.TrackFile(this.OutputPath, TrackedFileType.Final);
438 + trackedFiles.Add(trackMsi);
439
435 - var temporaryFiles = this.GenerateDatabase(output, trackMsi.Path, false, false);
436 - trackedFiles.AddRange(temporaryFiles);
440 + var temporaryFiles = this.GenerateDatabase(output, tableDefinitions, trackMsi.Path, false, false);
441 + trackedFiles.AddRange(temporaryFiles);
442 + }
443
444 // Stop processing if an error previously occurred.
445 if (this.Messaging.EncounteredError)
@@ -456,7 +462,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
462
463 if (null == sequenceTable)
464 {
459 - sequenceTable = output.EnsureTable(this.TableDefinitions[sequenceTableName]);
465 + sequenceTable = output.EnsureTable(tableDefinitions[sequenceTableName]);
466 }
467
468 if (0 == sequenceTable.Rows.Count)
@@ -911,7 +917,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
917 /// <param name="databaseFile">The database file to create.</param>
918 /// <param name="keepAddedColumns">Whether to keep columns added in a transform.</param>
919 /// <param name="useSubdirectory">Whether to use a subdirectory based on the <paramref name="databaseFile"/> file name for intermediate files.</param>
914 - private IEnumerable<ITrackedFile> GenerateDatabase(Output output, string databaseFile, bool keepAddedColumns, bool useSubdirectory)
920 + private IEnumerable<ITrackedFile> GenerateDatabase(Output output, TableDefinitionCollection tableDefinitions, string databaseFile, bool keepAddedColumns, bool useSubdirectory)
921 {
922 var command = new GenerateDatabaseCommand();
923 command.BackendHelper = this.BackendHelper;
@@ -921,7 +927,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
927 command.KeepAddedColumns = keepAddedColumns;
928 command.UseSubDirectory = useSubdirectory;
929 command.SuppressAddingValidationRows = this.SuppressAddingValidationRows;
924 - command.TableDefinitions = this.TableDefinitions;
930 + command.TableDefinitions = tableDefinitions;
931 command.IntermediateFolder = this.IntermediateFolder;
932 command.Codepage = this.Codepage;
933 command.Execute();
src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs
+118 -1
@@ -11,14 +11,18 @@ namespace WixToolset.Core.WindowsInstaller.Bind
11 using WixToolset.Data.WindowsInstaller;
12 using WixToolset.Data.WindowsInstaller.Rows;
13 using WixToolset.Extensibility;
14 + using WixToolset.Extensibility.Services;
15
16 internal class CreateOutputFromIRCommand
17 {
18 private const int DefaultMaximumUncompressedMediaSize = 200; // Default value is 200 MB
19 private const int MaxValueOfMaxCabSizeForLargeFileSplitting = 2 * 1024; // 2048 MB (i.e. 2 GB)
20
20 - public CreateOutputFromIRCommand(IntermediateSection section, TableDefinitionCollection tableDefinitions, IEnumerable<IWindowsInstallerBackendBinderExtension> backendExtensions)
21 + private static readonly char[] ColonCharacter = new[] { ':' };
22 +
23 + public CreateOutputFromIRCommand(IMessaging messaging, IntermediateSection section, TableDefinitionCollection tableDefinitions, IEnumerable<IWindowsInstallerBackendBinderExtension> backendExtensions)
24 {
25 + this.Messaging = messaging;
26 this.Section = section;
27 this.TableDefinitions = tableDefinitions;
28 this.BackendExtensions = backendExtensions;
@@ -26,6 +30,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
30
31 private IEnumerable<IWindowsInstallerBackendBinderExtension> BackendExtensions { get; }
32
33 + private IMessaging Messaging { get; }
34 +
35 private TableDefinitionCollection TableDefinitions { get; }
36
37 private IntermediateSection Section { get; }
@@ -49,6 +55,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
55 {
56 switch (tuple.Definition.Type)
57 {
58 + case TupleDefinitionType.AppSearch:
59 + this.AddTupleDefaultly(tuple, output);
60 + output.EnsureTable(this.TableDefinitions["Signature"]);
61 + break;
62 +
63 case TupleDefinitionType.Binary:
64 this.AddTupleDefaultly(tuple, output, idIsPrimaryKey: true);
65 break;
@@ -133,6 +144,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
144 this.AddMoveFileTuple((MoveFileTuple)tuple, output);
145 break;
146
147 + case TupleDefinitionType.ProgId:
148 + this.AddTupleDefaultly(tuple, output);
149 + output.EnsureTable(this.TableDefinitions["Extension"]);
150 + break;
151 +
152 case TupleDefinitionType.Property:
153 this.AddPropertyTuple((PropertyTuple)tuple, output);
154 break;
@@ -197,6 +213,14 @@ namespace WixToolset.Core.WindowsInstaller.Bind
213 this.AddTupleFromExtension(tuple, output);
214 break;
215
216 + case TupleDefinitionType.WixCustomRow:
217 + this.AddWixCustomRowTuple((WixCustomRowTuple)tuple, output);
218 + break;
219 +
220 + case TupleDefinitionType.WixEnsureTable:
221 + this.AddWixEnsureTableTuple((WixEnsureTableTuple)tuple, output);
222 + break;
223 +
224 // ignored.
225 case TupleDefinitionType.WixFile:
226 case TupleDefinitionType.WixComponentGroup:
@@ -204,6 +228,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind
228 case TupleDefinitionType.WixFeatureGroup:
229 break;
230
231 + // Already processed.
232 + case TupleDefinitionType.WixCustomTable:
233 + break;
234 +
235 default:
236 this.AddTupleDefaultly(tuple, output);
237 break;
@@ -382,6 +410,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
410 row[7] = tuple.FirstControlRef;
411 row[8] = tuple.DefaultControlRef;
412 row[9] = tuple.CancelControlRef;
413 +
414 + output.EnsureTable(this.TableDefinitions["ListBox"]);
415 }
416
417 private void AddDirectoryTuple(DirectoryTuple tuple, Output output)
@@ -929,6 +959,93 @@ namespace WixToolset.Core.WindowsInstaller.Bind
959 row[2] = tuple.Sequence;
960 }
961 }
962 +
963 + private void AddWixCustomRowTuple(WixCustomRowTuple tuple, Output output)
964 + {
965 + var customTableDefinition = this.TableDefinitions[tuple.Table];
966 +
967 + if (customTableDefinition.Unreal)
968 + {
969 +
970 + return;
971 + }
972 +
973 + var customTable = output.EnsureTable(customTableDefinition);
974 + var customRow = customTable.CreateRow(tuple.SourceLineNumbers);
975 +
976 +#if TODO // SectionId seems like a good thing to preserve.
977 + customRow.SectionId = tuple.SectionId;
978 +#endif
979 +
980 + var data = tuple.FieldDataSeparated;
981 +
982 + for (var i = 0; i < data.Length; ++i)
983 + {
984 + var foundColumn = false;
985 + var item = data[i].Split(ColonCharacter, 2);
986 +
987 + for (var j = 0; j < customRow.Fields.Length; ++j)
988 + {
989 + if (customRow.Fields[j].Column.Name == item[0])
990 + {
991 + if (0 < item[1].Length)
992 + {
993 + if (ColumnType.Number == customRow.Fields[j].Column.Type)
994 + {
995 + try
996 + {
997 + customRow.Fields[j].Data = Convert.ToInt32(item[1], CultureInfo.InvariantCulture);
998 + }
999 + catch (FormatException)
1000 + {
1001 + this.Messaging.Write(ErrorMessages.IllegalIntegerValue(tuple.SourceLineNumbers, customTableDefinition.Columns[i].Name, customTableDefinition.Name, item[1]));
1002 + }
1003 + catch (OverflowException)
1004 + {
1005 + this.Messaging.Write(ErrorMessages.IllegalIntegerValue(tuple.SourceLineNumbers, customTableDefinition.Columns[i].Name, customTableDefinition.Name, item[1]));
1006 + }
1007 + }
1008 + else if (ColumnCategory.Identifier == customRow.Fields[j].Column.Category)
1009 + {
1010 + if (Common.IsIdentifier(item[1]) || Common.IsValidBinderVariable(item[1]) || ColumnCategory.Formatted == customRow.Fields[j].Column.Category)
1011 + {
1012 + customRow.Fields[j].Data = item[1];
1013 + }
1014 + else
1015 + {
1016 + this.Messaging.Write(ErrorMessages.IllegalIdentifier(tuple.SourceLineNumbers, "Data", item[1]));
1017 + }
1018 + }
1019 + else
1020 + {
1021 + customRow.Fields[j].Data = item[1];
1022 + }
1023 + }
1024 + foundColumn = true;
1025 + break;
1026 + }
1027 + }
1028 +
1029 + if (!foundColumn)
1030 + {
1031 + this.Messaging.Write(ErrorMessages.UnexpectedCustomTableColumn(tuple.SourceLineNumbers, item[0]));
1032 + }
1033 + }
1034 +
1035 + for (var i = 0; i < customTableDefinition.Columns.Length; ++i)
1036 + {
1037 + if (!customTableDefinition.Columns[i].Nullable && (null == customRow.Fields[i].Data || 0 == customRow.Fields[i].Data.ToString().Length))
1038 + {
1039 + this.Messaging.Write(ErrorMessages.NoDataForColumn(tuple.SourceLineNumbers, customTableDefinition.Columns[i].Name, customTableDefinition.Name));
1040 + }
1041 + }
1042 + }
1043 +
1044 + private void AddWixEnsureTableTuple(WixEnsureTableTuple tuple, Output output)
1045 + {
1046 + var tableDefinition = this.TableDefinitions[tuple.Table];
1047 + output.EnsureTable(tableDefinition);
1048 + }
1049
1050 private void AddWixMediaTemplateTuple(WixMediaTemplateTuple tuple, Output output)
1051 {
src/WixToolset.Core.WindowsInstaller/Bind/LoadTableDefinitionsCommand.cs new
+213
@@ -0,0 +1,213 @@
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.Core.WindowsInstaller.Bind
4 +{
5 + using System;
6 + using System.Collections.Generic;
7 + using System.Globalization;
8 + using System.Linq;
9 + using WixToolset.Data;
10 + using WixToolset.Data.Tuples;
11 + using WixToolset.Data.WindowsInstaller;
12 +
13 + internal class LoadTableDefinitionsCommand
14 + {
15 + public LoadTableDefinitionsCommand(IntermediateSection section) => this.Section = section;
16 +
17 + public TableDefinitionCollection TableDefinitions { get; private set; }
18 +
19 + private IntermediateSection Section { get; }
20 +
21 + public TableDefinitionCollection Execute()
22 + {
23 + var tableDefinitions = new TableDefinitionCollection(WindowsInstallerStandardInternal.GetTableDefinitions());
24 +
25 + foreach (var tuple in this.Section.Tuples.OfType<WixCustomTableTuple>())
26 + {
27 + var customTableDefinition = this.CreateCustomTable(tuple);
28 + tableDefinitions.Add(customTableDefinition);
29 + }
30 +
31 + this.TableDefinitions = tableDefinitions;
32 + return this.TableDefinitions;
33 + }
34 +
35 + private TableDefinition CreateCustomTable(WixCustomTableTuple row)
36 + {
37 + var columnNames = row.ColumnNames.Split('\t');
38 + var columnTypes = row.ColumnTypes.Split('\t');
39 + var primaryKeys = row.PrimaryKeys.Split('\t');
40 + var minValues = row.MinValues?.Split('\t');
41 + var maxValues = row.MaxValues?.Split('\t');
42 + var keyTables = row.KeyTables?.Split('\t');
43 + var keyColumns = row.KeyColumns?.Split('\t');
44 + var categories = row.Categories?.Split('\t');
45 + var sets = row.Sets?.Split('\t');
46 + var descriptions = row.Descriptions?.Split('\t');
47 + var modularizations = row.Modularizations?.Split('\t');
48 +
49 + var currentPrimaryKey = 0;
50 +
51 + var columns = new List<ColumnDefinition>(columnNames.Length);
52 + for (var i = 0; i < columnNames.Length; ++i)
53 + {
54 + var name = columnNames[i];
55 + var type = ColumnType.Unknown;
56 +
57 + if (columnTypes[i].StartsWith("s", StringComparison.OrdinalIgnoreCase))
58 + {
59 + type = ColumnType.String;
60 + }
61 + else if (columnTypes[i].StartsWith("l", StringComparison.OrdinalIgnoreCase))
62 + {
63 + type = ColumnType.Localized;
64 + }
65 + else if (columnTypes[i].StartsWith("i", StringComparison.OrdinalIgnoreCase))
66 + {
67 + type = ColumnType.Number;
68 + }
69 + else if (columnTypes[i].StartsWith("v", StringComparison.OrdinalIgnoreCase))
70 + {
71 + type = ColumnType.Object;
72 + }
73 +
74 + var nullable = columnTypes[i].Substring(0, 1) == columnTypes[i].Substring(0, 1).ToUpperInvariant();
75 + var length = Convert.ToInt32(columnTypes[i].Substring(1), CultureInfo.InvariantCulture);
76 +
77 + var primaryKey = false;
78 + if (currentPrimaryKey < primaryKeys.Length && primaryKeys[currentPrimaryKey] == columnNames[i])
79 + {
80 + primaryKey = true;
81 + currentPrimaryKey++;
82 + }
83 +
84 + var minValue = String.IsNullOrEmpty(minValues?[i]) ? (int?)null : Convert.ToInt32(minValues[i], CultureInfo.InvariantCulture);
85 + var maxValue = String.IsNullOrEmpty(maxValues?[i]) ? (int?)null : Convert.ToInt32(maxValues[i], CultureInfo.InvariantCulture);
86 + var keyColumn = String.IsNullOrEmpty(keyColumns?[i]) ? (int?)null : Convert.ToInt32(keyColumns[i], CultureInfo.InvariantCulture);
87 +
88 + var category = ColumnCategory.Unknown;
89 + if (null != categories && null != categories[i] && 0 < categories[i].Length)
90 + {
91 + switch (categories[i])
92 + {
93 + case "Text":
94 + category = ColumnCategory.Text;
95 + break;
96 + case "UpperCase":
97 + category = ColumnCategory.UpperCase;
98 + break;
99 + case "LowerCase":
100 + category = ColumnCategory.LowerCase;
101 + break;
102 + case "Integer":
103 + category = ColumnCategory.Integer;
104 + break;
105 + case "DoubleInteger":
106 + category = ColumnCategory.DoubleInteger;
107 + break;
108 + case "TimeDate":
109 + category = ColumnCategory.TimeDate;
110 + break;
111 + case "Identifier":
112 + category = ColumnCategory.Identifier;
113 + break;
114 + case "Property":
115 + category = ColumnCategory.Property;
116 + break;
117 + case "Filename":
118 + category = ColumnCategory.Filename;
119 + break;
120 + case "WildCardFilename":
121 + category = ColumnCategory.WildCardFilename;
122 + break;
123 + case "Path":
124 + category = ColumnCategory.Path;
125 + break;
126 + case "Paths":
127 + category = ColumnCategory.Paths;
128 + break;
129 + case "AnyPath":
130 + category = ColumnCategory.AnyPath;
131 + break;
132 + case "DefaultDir":
133 + category = ColumnCategory.DefaultDir;
134 + break;
135 + case "RegPath":
136 + category = ColumnCategory.RegPath;
137 + break;
138 + case "Formatted":
139 + category = ColumnCategory.Formatted;
140 + break;
141 + case "FormattedSddl":
142 + category = ColumnCategory.FormattedSDDLText;
143 + break;
144 + case "Template":
145 + category = ColumnCategory.Template;
146 + break;
147 + case "Condition":
148 + category = ColumnCategory.Condition;
149 + break;
150 + case "Guid":
151 + category = ColumnCategory.Guid;
152 + break;
153 + case "Version":
154 + category = ColumnCategory.Version;
155 + break;
156 + case "Language":
157 + category = ColumnCategory.Language;
158 + break;
159 + case "Binary":
160 + category = ColumnCategory.Binary;
161 + break;
162 + case "CustomSource":
163 + category = ColumnCategory.CustomSource;
164 + break;
165 + case "Cabinet":
166 + category = ColumnCategory.Cabinet;
167 + break;
168 + case "Shortcut":
169 + category = ColumnCategory.Shortcut;
170 + break;
171 + default:
172 + break;
173 + }
174 + }
175 +
176 + var keyTable = keyTables?[i];
177 + var setValue = sets?[i];
178 + var description = descriptions?[i];
179 + var modString = modularizations?[i];
180 + var modularization = ColumnModularizeType.None;
181 +
182 + switch (modString)
183 + {
184 + case null:
185 + case "None":
186 + modularization = ColumnModularizeType.None;
187 + break;
188 + case "Column":
189 + modularization = ColumnModularizeType.Column;
190 + break;
191 + case "Property":
192 + modularization = ColumnModularizeType.Property;
193 + break;
194 + case "Condition":
195 + modularization = ColumnModularizeType.Condition;
196 + break;
197 + case "CompanionFile":
198 + modularization = ColumnModularizeType.CompanionFile;
199 + break;
200 + case "SemicolonDelimited":
201 + modularization = ColumnModularizeType.SemicolonDelimited;
202 + break;
203 + }
204 +
205 + var columnDefinition = new ColumnDefinition(name, type, length, primaryKey, nullable, category, minValue, maxValue, keyTable, keyColumn, setValue, description, modularization, ColumnType.Localized == type, true);
206 + columns.Add(columnDefinition);
207 + }
208 +
209 + var customTable = new TableDefinition(row.Id.Id, columns/*, unreal: bootstrapperApplicationData, bootstrapperApplicationData*/);
210 + return customTable;
211 + }
212 + }
213 +}
src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs
+1 -1
@@ -271,7 +271,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
271 }
272 }
273
274 - var tableDefinition = new TableDefinition(tableName, columns, false, false);
274 + var tableDefinition = new TableDefinition(tableName, columns, false);
275
276 // use our table definitions if core properties are the same; this allows us to take advantage
277 // of wix concepts like localizable columns which current code assumes
src/WixToolset.Core/Common.cs
-2
@@ -104,8 +104,6 @@ namespace WixToolset.Core
104
105 public static readonly Regex WixVariableRegex = new Regex(@"(\!|\$)\((?<namespace>loc|wix|bind|bindpath)\.(?<fullname>(?<name>[_A-Za-z][0-9A-Za-z_]+)(\.(?<scope>[_A-Za-z][0-9A-Za-z_\.]*))?)(\=(?<value>.+?))?\)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture);
106
107 - internal const char CustomRowFieldSeparator = '\x85';
108 -
107 private static readonly Regex PropertySearch = new Regex(@"\[[#$!]?[a-zA-Z_][a-zA-Z0-9_\.]*]", RegexOptions.Singleline);
108 private static readonly Regex AddPrefix = new Regex(@"^[^a-zA-Z_]", RegexOptions.Compiled);
109 private static readonly Regex LegalIdentifierCharacters = new Regex(@"^[_A-Za-z][0-9A-Za-z_\.]*$", RegexOptions.Compiled);
src/WixToolset.Core/Compiler.cs
+3 -3
@@ -3750,7 +3750,7 @@ namespace WixToolset.Core
3750 case "Id":
3751 tableId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3752 break;
3753 - case "BootstrapperApplicationData":
3753 + case "Unreal":
3754 bootstrapperApplicationData = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
3755 break;
3756 default:
@@ -3951,7 +3951,7 @@ namespace WixToolset.Core
3951 this.Core.Write(ErrorMessages.ExpectedAttribute(dataSourceLineNumbers, data.Name.LocalName, "Column"));
3952 }
3953
3954 - dataValue = String.Concat(dataValue, null == dataValue ? String.Empty : Common.CustomRowFieldSeparator.ToString(), columnName, ":", Common.GetInnerText(data));
3954 + dataValue = String.Concat(dataValue, null == dataValue ? String.Empty : WixCustomRowTuple.FieldSeparator.ToString(), columnName, ":", Common.GetInnerText(data));
3955 break;
3956 }
3957 }
@@ -4001,7 +4001,7 @@ namespace WixToolset.Core
4001 Sets = sets,
4002 Descriptions = descriptions,
4003 Modularizations = modularizations,
4004 - BootstrapperApplicationData = bootstrapperApplicationData
4004 + Unreal = bootstrapperApplicationData
4005 };
4006
4007 this.Core.AddTuple(tuple);
src/WixToolset.Core/Librarian.cs
+16 -21
@@ -30,7 +30,6 @@ namespace WixToolset.Core
30 /// <summary>
31 /// Create a library by combining several intermediates (objects).
32 /// </summary>
33 - /// <param name="sections">The sections to combine into a library.</param>
33 /// <returns>Returns the new library.</returns>
34 public Intermediate Combine(ILibraryContext context)
35 {
@@ -79,26 +78,6 @@ namespace WixToolset.Core
78 return this.Messaging.EncounteredError ? null : library;
79 }
80
82 - /// <summary>
83 - /// Validate that a library contains one entry section and no duplicate symbols.
84 - /// </summary>
85 - /// <param name="library">Library to validate.</param>
86 - private void Validate(Intermediate library)
87 - {
88 - var find = new FindEntrySectionAndLoadSymbolsCommand(this.Messaging, library.Sections);
89 - find.Execute();
90 -
91 - // TODO: Consider bringing this sort of verification back.
92 - // foreach (Section section in library.Sections)
93 - // {
94 - // ResolveReferencesCommand resolve = new ResolveReferencesCommand(find.EntrySection, find.Symbols);
95 - // resolve.Execute();
96 - //
97 - // ReportDuplicateResolvedSymbolErrorsCommand reportDupes = new ReportDuplicateResolvedSymbolErrorsCommand(find.SymbolsWithDuplicates, resolve.ResolvedSections);
98 - // reportDupes.Execute();
99 - // }
100 - }
101 -
81 private List<string> ResolveFilePathsToEmbed(ILibraryContext context, IEnumerable<IntermediateSection> sections)
82 {
83 var embedFilePaths = new List<string>();
@@ -140,5 +119,21 @@ namespace WixToolset.Core
119
120 return embedFilePaths;
121 }
122 +
123 + private void Validate(Intermediate library)
124 + {
125 + var find = new FindEntrySectionAndLoadSymbolsCommand(this.Messaging, library.Sections, OutputType.Library);
126 + find.Execute();
127 +
128 + // TODO: Consider bringing this sort of verification back.
129 + // foreach (Section section in library.Sections)
130 + // {
131 + // ResolveReferencesCommand resolve = new ResolveReferencesCommand(find.EntrySection, find.Symbols);
132 + // resolve.Execute();
133 + //
134 + // ReportDuplicateResolvedSymbolErrorsCommand reportDupes = new ReportDuplicateResolvedSymbolErrorsCommand(find.SymbolsWithDuplicates, resolve.ResolvedSections);
135 + // reportDupes.Execute();
136 + // }
137 + }
138 }
139 }
src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs
+7 -9
@@ -10,20 +10,18 @@ namespace WixToolset.Core.Link
10
11 internal class FindEntrySectionAndLoadSymbolsCommand
12 {
13 - public FindEntrySectionAndLoadSymbolsCommand(IMessaging messaging, IEnumerable<IntermediateSection> sections)
13 + public FindEntrySectionAndLoadSymbolsCommand(IMessaging messaging, IEnumerable<IntermediateSection> sections, OutputType expectedOutpuType)
14 {
15 this.Messaging = messaging;
16 this.Sections = sections;
17 + this.ExpectedOutputType = expectedOutpuType;
18 }
19
20 private IMessaging Messaging { get; }
21
22 private IEnumerable<IntermediateSection> Sections { get; }
23
23 - /// <summary>
24 - /// Sets the expected entry output type, based on output file extension provided to the linker.
25 - /// </summary>
26 - public OutputType ExpectedOutputType { private get; set; }
24 + private OutputType ExpectedOutputType { get; }
25
26 /// <summary>
27 /// Gets the located entry section after the command is executed.
@@ -42,8 +40,8 @@ namespace WixToolset.Core.Link
40
41 public void Execute()
42 {
45 - Dictionary<string, Symbol> symbols = new Dictionary<string, Symbol>();
46 - HashSet<Symbol> possibleConflicts = new HashSet<Symbol>();
43 + var symbols = new Dictionary<string, Symbol>();
44 + var possibleConflicts = new HashSet<Symbol>();
45
46 if (!Enum.TryParse(this.ExpectedOutputType.ToString(), out SectionType expectedEntrySectionType))
47 {
@@ -74,9 +72,9 @@ namespace WixToolset.Core.Link
72 }
73
74 // Load all the symbols from the section's tables that create symbols.
77 - foreach (var row in section.Tuples.Where(t => t.Id != null))
75 + foreach (var tuple in section.Tuples.Where(t => t.Id != null))
76 {
79 - var symbol = new Symbol(section, row);
77 + var symbol = new Symbol(section, tuple);
78
79 if (!symbols.TryGetValue(symbol.Name, out var existingSymbol))
80 {
src/WixToolset.Core/Link/ResolveReferencesCommand.cs
+6 -5
@@ -14,8 +14,8 @@ namespace WixToolset.Core.Link
14 /// </summary>
15 internal class ResolveReferencesCommand
16 {
17 - private IntermediateSection entrySection;
18 - private IDictionary<string, Symbol> symbols;
17 + private readonly IntermediateSection entrySection;
18 + private readonly IDictionary<string, Symbol> symbols;
19 private HashSet<Symbol> referencedSymbols;
20 private HashSet<IntermediateSection> resolvedSections;
21
@@ -24,13 +24,14 @@ namespace WixToolset.Core.Link
24 this.Messaging = messaging;
25 this.entrySection = entrySection;
26 this.symbols = symbols;
27 + this.BuildingMergeModule = (SectionType.Module == entrySection.Type);
28 }
29
29 - public bool BuildingMergeModule { private get; set; }
30 + public IEnumerable<Symbol> ReferencedSymbols => this.referencedSymbols;
31
31 - public IEnumerable<Symbol> ReferencedSymbols { get { return this.referencedSymbols; } }
32 + public IEnumerable<IntermediateSection> ResolvedSections => this.resolvedSections;
33
33 - public IEnumerable<IntermediateSection> ResolvedSections { get { return this.resolvedSections; } }
34 + private bool BuildingMergeModule { get; }
35
36 private IMessaging Messaging { get; }
37
src/WixToolset.Core/Linker.cs
+41 -418
@@ -20,7 +20,6 @@ namespace WixToolset.Core
20 /// </summary>
21 internal class Linker : ILinker
22 {
23 - private static readonly char[] ColonCharacter = new[] { ':' };
23 private static readonly string EmptyGuid = Guid.Empty.ToString("B");
24
25 private readonly bool sectionIdOnRows;
@@ -56,9 +55,7 @@ namespace WixToolset.Core
55 /// <summary>
56 /// Links a collection of sections into an output.
57 /// </summary>
59 - /// <param name="inputs">The collection of sections to link together.</param>
60 - /// <param name="expectedOutputType">Expected output type, based on output file extension provided to the linker.</param>
61 - /// <returns>Output object from the linking.</returns>
58 + /// <returns>Output intermediate from the linking.</returns>
59 public Intermediate Link(ILinkContext context)
60 {
61 this.Context = context;
@@ -97,9 +94,6 @@ namespace WixToolset.Core
94
95 //this.activeOutput = null;
96
100 - //TableDefinitionCollection customTableDefinitions = new TableDefinitionCollection();
101 - //IntermediateTuple customRows = new List<IntermediateTuple>();
102 -
97 #if MOVE_TO_BACKEND
98 StringCollection generatedShortFileNameIdentifiers = new StringCollection();
99 Hashtable generatedShortFileNames = new Hashtable();
@@ -123,11 +117,11 @@ namespace WixToolset.Core
117
118 if (0 >= columnDefinition.KeyColumn || keyTableDefinition.Columns.Count < columnDefinition.KeyColumn)
119 {
126 - this.OnMessage(WixErrors.InvalidKeyColumn(tableDefinition.Name, columnDefinition.Name, columnDefinition.KeyTable, columnDefinition.KeyColumn));
120 + this.Messaging.Write(WixErrors.InvalidKeyColumn(tableDefinition.Name, columnDefinition.Name, columnDefinition.KeyTable, columnDefinition.KeyColumn));
121 }
122 else if (keyTableDefinition.Columns[columnDefinition.KeyColumn - 1].ModularizeType != columnDefinition.ModularizeType && ColumnModularizeType.CompanionFile != columnDefinition.ModularizeType)
123 {
130 - this.OnMessage(WixErrors.CollidingModularizationTypes(tableDefinition.Name, columnDefinition.Name, columnDefinition.KeyTable, columnDefinition.KeyColumn, columnDefinition.ModularizeType.ToString(), keyTableDefinition.Columns[columnDefinition.KeyColumn - 1].ModularizeType.ToString()));
124 + this.Messaging.Write(WixErrors.CollidingModularizationTypes(tableDefinition.Name, columnDefinition.Name, columnDefinition.KeyTable, columnDefinition.KeyColumn, columnDefinition.ModularizeType.ToString(), keyTableDefinition.Columns[columnDefinition.KeyColumn - 1].ModularizeType.ToString()));
125 }
126 }
127 catch (WixMissingTableDefinitionException)
@@ -141,8 +135,7 @@ namespace WixToolset.Core
135
136 // First find the entry section and while processing all sections load all the symbols from all of the sections.
137 // sections.FindEntrySectionAndLoadSymbols(false, this, expectedOutputType, out entrySection, out allSymbols);
144 - var find = new FindEntrySectionAndLoadSymbolsCommand(this.Messaging, sections);
145 - find.ExpectedOutputType = this.Context.ExpectedOutputType;
138 + var find = new FindEntrySectionAndLoadSymbolsCommand(this.Messaging, sections, this.Context.ExpectedOutputType);
139 find.Execute();
140
141 // Must have found the entry section by now.
@@ -157,7 +150,6 @@ namespace WixToolset.Core
150 // Resolve the symbol references to find the set of sections we care about for linking.
151 // Of course, we start with the entry section (that's how it got its name after all).
152 var resolve = new ResolveReferencesCommand(this.Messaging, find.EntrySection, find.Symbols);
160 - resolve.BuildingMergeModule = (SectionType.Module == find.EntrySection.Type);
153
154 resolve.Execute();
155
@@ -197,7 +189,7 @@ namespace WixToolset.Core
189 {
190 if (!referencedComponents.Contains(symbol.Name))
191 {
200 - this.OnMessage(ErrorMessages.OrphanedComponent(symbol.Row.SourceLineNumbers, symbol.Row.Id.Id));
192 + this.Messaging.Write(ErrorMessages.OrphanedComponent(symbol.Row.SourceLineNumbers, symbol.Row.Id.Id));
193 }
194 }
195
@@ -238,12 +230,6 @@ namespace WixToolset.Core
230 // handle special tables
231 switch (tuple.Definition.Type)
232 {
241 -#if MOVE_TO_BACKEND
242 - case "AppSearch":
243 - this.activeOutput.EnsureTable(this.tableDefinitions["Signature"]);
244 - break;
245 -#endif
246 -
233 case TupleDefinitionType.Class:
234 if (SectionType.Product == resolvedSection.Type)
235 {
@@ -263,10 +249,6 @@ namespace WixToolset.Core
249 }
250 break;
251
266 - case "Dialog":
267 - this.activeOutput.EnsureTable(this.tableDefinitions["ListBox"]);
268 - break;
269 -
252 case "Directory":
253 foreach (Row row in table.Rows)
254 {
@@ -295,7 +277,7 @@ namespace WixToolset.Core
277 {
278 if (directory.StartsWith(standardDirectory, StringComparison.Ordinal))
279 {
298 - this.OnMessage(WixWarnings.StandardDirectoryConflictInMergeModule(row.SourceLineNumbers, directory, standardDirectory));
280 + this.Messaging.Write(WixWarnings.StandardDirectoryConflictInMergeModule(row.SourceLineNumbers, directory, standardDirectory));
281 }
282 }
283 }
@@ -327,26 +309,6 @@ namespace WixToolset.Core
309 }
310 break;
311
330 -#if MOVE_TO_BACKEND
331 - case "ProgId":
332 - // the Extension table is required with a ProgId table
333 - this.activeOutput.EnsureTable(this.tableDefinitions["Extension"]);
334 - break;
335 -
336 - case "Property":
337 - // Remove property rows with no value. These are properties associated with
338 - // AppSearch but without a default value.
339 - for (int i = 0; i < table.Rows.Count; i++)
340 - {
341 - if (null == table.Rows[i][1])
342 - {
343 - table.Rows.RemoveAt(i);
344 - i--;
345 - }
346 - }
347 - break;
348 -#endif
349 -
312 case TupleDefinitionType.PublishComponent:
313 if (SectionType.Product == resolvedSection.Type)
314 {
@@ -368,27 +330,10 @@ namespace WixToolset.Core
330 }
331 break;
332
371 -#if SOLVE_CUSTOM_TABLE
372 - case "WixCustomTable":
373 - this.LinkCustomTable(table, customTableDefinitions);
374 - copyTuple = false; // we've created table definitions from these rows, no need to process them any longer
375 - break;
376 -
377 - case "WixCustomRow":
378 - foreach (Row row in table.Rows)
379 - {
380 - row.SectionId = (this.sectionIdOnRows ? sectionId : null);
381 - customRows.Add(row);
382 - }
383 - copyTuple = false;
384 - break;
385 -#endif
386 -
333 case TupleDefinitionType.WixEnsureTable:
334 ensureTableRows.Add(tuple);
335 break;
336
391 -
337 #if MOVE_TO_BACKEND
338 case "WixFile":
339 foreach (Row row in table.Rows)
@@ -427,23 +372,23 @@ namespace WixToolset.Core
372 case TupleDefinitionType.WixVariable:
373 // check for colliding values and collect the wix variable rows
374 {
430 - var row = (WixVariableTuple)tuple;
431 - var id = row.Id.Id;
375 + var wixVariableTuple = (WixVariableTuple)tuple;
376 + var id = wixVariableTuple.Id.Id;
377
433 - if (wixVariables.TryGetValue(id, out var collidingRow))
378 + if (wixVariables.TryGetValue(id, out var collidingTuple))
379 {
435 - if (collidingRow.Overridable && !row.Overridable)
380 + if (collidingTuple.Overridable && !wixVariableTuple.Overridable)
381 {
437 - wixVariables[id] = row;
382 + wixVariables[id] = wixVariableTuple;
383 }
439 - else if (!row.Overridable || (collidingRow.Overridable && row.Overridable))
384 + else if (!wixVariableTuple.Overridable || (collidingTuple.Overridable && wixVariableTuple.Overridable))
385 {
441 - this.OnMessage(ErrorMessages.WixVariableCollision(row.SourceLineNumbers, id));
386 + this.Messaging.Write(ErrorMessages.WixVariableCollision(wixVariableTuple.SourceLineNumbers, id));
387 }
388 }
389 else
390 {
446 - wixVariables.Add(id, row);
391 + wixVariables.Add(id, wixVariableTuple);
392 }
393 }
394
@@ -463,36 +408,15 @@ namespace WixToolset.Core
408 {
409 foreach (var feature in connectToFeature.ConnectFeatures)
410 {
466 - var row = new WixFeatureModulesTuple();
467 - row.FeatureRef = feature;
468 - row.WixMergeRef = connectToFeature.ChildId;
469 -
470 - resolvedSection.Tuples.Add(row);
471 - }
472 - }
473 -
474 -#if MOVE_TO_BACKEND
475 - // ensure the creation of tables that need to exist
476 - if (0 < ensureTableRows.Count)
477 - {
478 - foreach (Row row in ensureTableRows)
479 - {
480 - string tableId = (string)row[0];
481 - TableDefinition tableDef = null;
482 -
483 - try
411 + var row = new WixFeatureModulesTuple
412 {
485 - tableDef = this.tableDefinitions[tableId];
486 - }
487 - catch (WixMissingTableDefinitionException)
488 - {
489 - tableDef = customTableDefinitions[tableId];
490 - }
413 + FeatureRef = feature,
414 + WixMergeRef = connectToFeature.ChildId
415 + };
416
492 - this.activeOutput.EnsureTable(tableDef);
417 + resolvedSection.Tuples.Add(row);
418 }
419 }
495 -#endif
420
421 #if MOVE_TO_BACKEND
422 // check for missing table and add them or display an error as appropriate
@@ -513,17 +437,17 @@ namespace WixToolset.Core
437
438 if (null == imageFamiliesTable || 1 > imageFamiliesTable.Rows.Count)
439 {
516 - this.OnMessage(WixErrors.ExpectedRowInPatchCreationPackage("ImageFamilies"));
440 + this.Messaging.Write(WixErrors.ExpectedRowInPatchCreationPackage("ImageFamilies"));
441 }
442
443 if (null == targetImagesTable || 1 > targetImagesTable.Rows.Count)
444 {
521 - this.OnMessage(WixErrors.ExpectedRowInPatchCreationPackage("TargetImages"));
445 + this.Messaging.Write(WixErrors.ExpectedRowInPatchCreationPackage("TargetImages"));
446 }
447
448 if (null == upgradedImagesTable || 1 > upgradedImagesTable.Rows.Count)
449 {
526 - this.OnMessage(WixErrors.ExpectedRowInPatchCreationPackage("UpgradedImages"));
450 + this.Messaging.Write(WixErrors.ExpectedRowInPatchCreationPackage("UpgradedImages"));
451 }
452
453 this.activeOutput.EnsureTable(this.tableDefinitions["Properties"]);
@@ -537,81 +461,6 @@ namespace WixToolset.Core
461 this.CheckForIllegalTables(this.activeOutput);
462 #endif
463
540 -#if SOLVE_CUSTOM_TABLE
541 - // add the custom row data
542 - foreach (Row row in customRows)
543 - {
544 - TableDefinition customTableDefinition = (TableDefinition)customTableDefinitions[row[0].ToString()];
545 - Table customTable = this.activeOutput.EnsureTable(customTableDefinition);
546 - Row customRow = customTable.CreateRow(row.SourceLineNumbers);
547 -
548 - customRow.SectionId = row.SectionId;
549 -
550 - string[] data = row[1].ToString().Split(Common.CustomRowFieldSeparator);
551 -
552 - for (int i = 0; i < data.Length; ++i)
553 - {
554 - bool foundColumn = false;
555 - string[] item = data[i].Split(colonCharacter, 2);
556 -
557 - for (int j = 0; j < customRow.Fields.Length; ++j)
558 - {
559 - if (customRow.Fields[j].Column.Name == item[0])
560 - {
561 - if (0 < item[1].Length)
562 - {
563 - if (ColumnType.Number == customRow.Fields[j].Column.Type)
564 - {
565 - try
566 - {
567 - customRow.Fields[j].Data = Convert.ToInt32(item[1], CultureInfo.InvariantCulture);
568 - }
569 - catch (FormatException)
570 - {
571 - this.OnMessage(WixErrors.IllegalIntegerValue(row.SourceLineNumbers, customTableDefinition.Columns[i].Name, customTableDefinition.Name, item[1]));
572 - }
573 - catch (OverflowException)
574 - {
575 - this.OnMessage(WixErrors.IllegalIntegerValue(row.SourceLineNumbers, customTableDefinition.Columns[i].Name, customTableDefinition.Name, item[1]));
576 - }
577 - }
578 - else if (ColumnCategory.Identifier == customRow.Fields[j].Column.Category)
579 - {
580 - if (Common.IsIdentifier(item[1]) || Common.IsValidBinderVariable(item[1]) || ColumnCategory.Formatted == customRow.Fields[j].Column.Category)
581 - {
582 - customRow.Fields[j].Data = item[1];
583 - }
584 - else
585 - {
586 - this.OnMessage(WixErrors.IllegalIdentifier(row.SourceLineNumbers, "Data", item[1]));
587 - }
588 - }
589 - else
590 - {
591 - customRow.Fields[j].Data = item[1];
592 - }
593 - }
594 - foundColumn = true;
595 - break;
596 - }
597 - }
598 -
599 - if (!foundColumn)
600 - {
601 - this.OnMessage(WixErrors.UnexpectedCustomTableColumn(row.SourceLineNumbers, item[0]));
602 - }
603 - }
604 -
605 - for (int i = 0; i < customTableDefinition.Columns.Count; ++i)
606 - {
607 - if (!customTableDefinition.Columns[i].Nullable && (null == customRow.Fields[i].Data || 0 == customRow.Fields[i].Data.ToString().Length))
608 - {
609 - this.OnMessage(WixErrors.NoDataForColumn(row.SourceLineNumbers, customTableDefinition.Columns[i].Name, customTableDefinition.Name));
610 - }
611 - }
612 - }
613 -#endif
614 -
464 //correct the section Id in FeatureComponents table
465 if (this.sectionIdOnRows)
466 {
@@ -683,7 +532,7 @@ namespace WixToolset.Core
532 // sort the rows by DiskId
533 fileRows.Sort();
534
686 - this.OnMessage(WixWarnings.GeneratedShortFileNameConflict(((FileRow)fileRows[0]).SourceLineNumbers, shortFileName));
535 + this.Messaging.Write(WixWarnings.GeneratedShortFileNameConflict(((FileRow)fileRows[0]).SourceLineNumbers, shortFileName));
536
537 for (int i = 1; i < fileRows.Count; i++)
538 {
@@ -691,7 +540,7 @@ namespace WixToolset.Core
540
541 if (null != fileRow.SourceLineNumbers)
542 {
694 - this.OnMessage(WixWarnings.GeneratedShortFileNameConflict2(fileRow.SourceLineNumbers));
543 + this.Messaging.Write(WixWarnings.GeneratedShortFileNameConflict2(fileRow.SourceLineNumbers));
544 }
545 }
546 }
@@ -732,223 +581,6 @@ namespace WixToolset.Core
581 return this.Messaging.EncounteredError ? null : intermediate;
582 }
583
735 -#if SOLVE_CUSTOM_TABLE
736 - /// <summary>
737 - /// Links the definition of a custom table.
738 - /// </summary>
739 - /// <param name="table">The table to link.</param>
740 - /// <param name="customTableDefinitions">Receives the linked definition of the custom table.</param>
741 - private void LinkCustomTable(Table table, TableDefinitionCollection customTableDefinitions)
742 - {
743 - foreach (Row row in table.Rows)
744 - {
745 - bool bootstrapperApplicationData = (null != row[13] && 1 == (int)row[13]);
746 -
747 - if (null == row[4])
748 - {
749 - this.OnMessage(WixErrors.ExpectedAttribute(row.SourceLineNumbers, "CustomTable/Column", "PrimaryKey"));
750 - }
751 -
752 - string[] columnNames = row[2].ToString().Split('\t');
753 - string[] columnTypes = row[3].ToString().Split('\t');
754 - string[] primaryKeys = row[4].ToString().Split('\t');
755 - string[] minValues = row[5] == null ? null : row[5].ToString().Split('\t');
756 - string[] maxValues = row[6] == null ? null : row[6].ToString().Split('\t');
757 - string[] keyTables = row[7] == null ? null : row[7].ToString().Split('\t');
758 - string[] keyColumns = row[8] == null ? null : row[8].ToString().Split('\t');
759 - string[] categories = row[9] == null ? null : row[9].ToString().Split('\t');
760 - string[] sets = row[10] == null ? null : row[10].ToString().Split('\t');
761 - string[] descriptions = row[11] == null ? null : row[11].ToString().Split('\t');
762 - string[] modularizations = row[12] == null ? null : row[12].ToString().Split('\t');
763 -
764 - int currentPrimaryKey = 0;
765 -
766 - List<ColumnDefinition> columns = new List<ColumnDefinition>(columnNames.Length);
767 - for (int i = 0; i < columnNames.Length; ++i)
768 - {
769 - string name = columnNames[i];
770 - ColumnType type = ColumnType.Unknown;
771 -
772 - if (columnTypes[i].StartsWith("s", StringComparison.OrdinalIgnoreCase))
773 - {
774 - type = ColumnType.String;
775 - }
776 - else if (columnTypes[i].StartsWith("l", StringComparison.OrdinalIgnoreCase))
777 - {
778 - type = ColumnType.Localized;
779 - }
780 - else if (columnTypes[i].StartsWith("i", StringComparison.OrdinalIgnoreCase))
781 - {
782 - type = ColumnType.Number;
783 - }
784 - else if (columnTypes[i].StartsWith("v", StringComparison.OrdinalIgnoreCase))
785 - {
786 - type = ColumnType.Object;
787 - }
788 - else
789 - {
790 - throw new WixException(WixErrors.UnknownCustomTableColumnType(row.SourceLineNumbers, columnTypes[i]));
791 - }
792 -
793 - bool nullable = columnTypes[i].Substring(0, 1) == columnTypes[i].Substring(0, 1).ToUpper(CultureInfo.InvariantCulture);
794 - int length = Convert.ToInt32(columnTypes[i].Substring(1), CultureInfo.InvariantCulture);
795 -
796 - bool primaryKey = false;
797 - if (currentPrimaryKey < primaryKeys.Length && primaryKeys[currentPrimaryKey] == columnNames[i])
798 - {
799 - primaryKey = true;
800 - currentPrimaryKey++;
801 - }
802 -
803 - bool minValSet = null != minValues && null != minValues[i] && 0 < minValues[i].Length;
804 - int minValue = 0;
805 - if (minValSet)
806 - {
807 - minValue = Convert.ToInt32(minValues[i], CultureInfo.InvariantCulture);
808 - }
809 -
810 - bool maxValSet = null != maxValues && null != maxValues[i] && 0 < maxValues[i].Length;
811 - int maxValue = 0;
812 - if (maxValSet)
813 - {
814 - maxValue = Convert.ToInt32(maxValues[i], CultureInfo.InvariantCulture);
815 - }
816 -
817 - bool keyColumnSet = null != keyColumns && null != keyColumns[i] && 0 < keyColumns[i].Length;
818 - int keyColumn = 0;
819 - if (keyColumnSet)
820 - {
821 - keyColumn = Convert.ToInt32(keyColumns[i], CultureInfo.InvariantCulture);
822 - }
823 -
824 - ColumnCategory category = ColumnCategory.Unknown;
825 - if (null != categories && null != categories[i] && 0 < categories[i].Length)
826 - {
827 - switch (categories[i])
828 - {
829 - case "Text":
830 - category = ColumnCategory.Text;
831 - break;
832 - case "UpperCase":
833 - category = ColumnCategory.UpperCase;
834 - break;
835 - case "LowerCase":
836 - category = ColumnCategory.LowerCase;
837 - break;
838 - case "Integer":
839 - category = ColumnCategory.Integer;
840 - break;
841 - case "DoubleInteger":
842 - category = ColumnCategory.DoubleInteger;
843 - break;
844 - case "TimeDate":
845 - category = ColumnCategory.TimeDate;
846 - break;
847 - case "Identifier":
848 - category = ColumnCategory.Identifier;
849 - break;
850 - case "Property":
851 - category = ColumnCategory.Property;
852 - break;
853 - case "Filename":
854 - category = ColumnCategory.Filename;
855 - break;
856 - case "WildCardFilename":
857 - category = ColumnCategory.WildCardFilename;
858 - break;
859 - case "Path":
860 - category = ColumnCategory.Path;
861 - break;
862 - case "Paths":
863 - category = ColumnCategory.Paths;
864 - break;
865 - case "AnyPath":
866 - category = ColumnCategory.AnyPath;
867 - break;
868 - case "DefaultDir":
869 - category = ColumnCategory.DefaultDir;
870 - break;
871 - case "RegPath":
872 - category = ColumnCategory.RegPath;
873 - break;
874 - case "Formatted":
875 - category = ColumnCategory.Formatted;
876 - break;
877 - case "FormattedSddl":
878 - category = ColumnCategory.FormattedSDDLText;
879 - break;
880 - case "Template":
881 - category = ColumnCategory.Template;
882 - break;
883 - case "Condition":
884 - category = ColumnCategory.Condition;
885 - break;
886 - case "Guid":
887 - category = ColumnCategory.Guid;
888 - break;
889 - case "Version":
890 - category = ColumnCategory.Version;
891 - break;
892 - case "Language":
893 - category = ColumnCategory.Language;
894 - break;
895 - case "Binary":
896 - category = ColumnCategory.Binary;
897 - break;
898 - case "CustomSource":
899 - category = ColumnCategory.CustomSource;
900 - break;
901 - case "Cabinet":
902 - category = ColumnCategory.Cabinet;
903 - break;
904 - case "Shortcut":
905 - category = ColumnCategory.Shortcut;
906 - break;
907 - default:
908 - break;
909 - }
910 - }
911 -
912 - string keyTable = keyTables != null ? keyTables[i] : null;
913 - string setValue = sets != null ? sets[i] : null;
914 - string description = descriptions != null ? descriptions[i] : null;
915 - string modString = modularizations != null ? modularizations[i] : null;
916 - ColumnModularizeType modularization = ColumnModularizeType.None;
917 - if (modString != null)
918 - {
919 - switch (modString)
920 - {
921 - case "None":
922 - modularization = ColumnModularizeType.None;
923 - break;
924 - case "Column":
925 - modularization = ColumnModularizeType.Column;
926 - break;
927 - case "Property":
928 - modularization = ColumnModularizeType.Property;
929 - break;
930 - case "Condition":
931 - modularization = ColumnModularizeType.Condition;
932 - break;
933 - case "CompanionFile":
934 - modularization = ColumnModularizeType.CompanionFile;
935 - break;
936 - case "SemicolonDelimited":
937 - modularization = ColumnModularizeType.SemicolonDelimited;
938 - break;
939 - }
940 - }
941 -
942 - ColumnDefinition columnDefinition = new ColumnDefinition(name, type, length, primaryKey, nullable, modularization, ColumnType.Localized == type, minValSet, minValue, maxValSet, maxValue, keyTable, keyColumnSet, keyColumn, category, setValue, description, true, true);
943 - columns.Add(columnDefinition);
944 - }
945 -
946 - TableDefinition customTable = new TableDefinition((string)row[0], columns, false, bootstrapperApplicationData, bootstrapperApplicationData);
947 - customTableDefinitions.Add(customTable);
948 - }
949 - }
950 -#endif
951 -
584 #if MOVE_TO_BACKEND
585 /// <summary>
586 /// Checks for any tables in the output which are not allowed in the output type.
@@ -973,14 +605,14 @@ namespace WixToolset.Core
605 {
606 foreach (Row row in table.Rows)
607 {
976 - this.OnMessage(WixErrors.UnexpectedTableInMergeModule(row.SourceLineNumbers, table.Name));
608 + this.Messaging.Write(WixErrors.UnexpectedTableInMergeModule(row.SourceLineNumbers, table.Name));
609 }
610 }
611 else if ("Error" == table.Name)
612 {
613 foreach (Row row in table.Rows)
614 {
983 - this.OnMessage(WixWarnings.DangerousTableInMergeModule(row.SourceLineNumbers, table.Name));
615 + this.Messaging.Write(WixWarnings.DangerousTableInMergeModule(row.SourceLineNumbers, table.Name));
616 }
617 }
618 break;
@@ -1001,7 +633,7 @@ namespace WixToolset.Core
633 {
634 foreach (Row row in table.Rows)
635 {
1004 - this.OnMessage(WixErrors.UnexpectedTableInPatchCreationPackage(row.SourceLineNumbers, table.Name));
636 + this.Messaging.Write(WixErrors.UnexpectedTableInPatchCreationPackage(row.SourceLineNumbers, table.Name));
637 }
638 }
639 break;
@@ -1014,7 +646,7 @@ namespace WixToolset.Core
646 {
647 foreach (Row row in table.Rows)
648 {
1017 - this.OnMessage(WixErrors.UnexpectedTableInPatch(row.SourceLineNumbers, table.Name));
649 + this.Messaging.Write(WixErrors.UnexpectedTableInPatch(row.SourceLineNumbers, table.Name));
650 }
651 }
652 break;
@@ -1035,7 +667,7 @@ namespace WixToolset.Core
667 {
668 foreach (Row row in table.Rows)
669 {
1038 - this.OnMessage(WixWarnings.UnexpectedTableInProduct(row.SourceLineNumbers, table.Name));
670 + this.Messaging.Write(WixWarnings.UnexpectedTableInProduct(row.SourceLineNumbers, table.Name));
671 }
672 }
673 break;
@@ -1080,7 +712,7 @@ namespace WixToolset.Core
712 {
713 foreach (Row row in isolatedComponentTable.Rows)
714 {
1083 - this.OnMessage(WixWarnings.TableIncompatibleWithInstallerVersion(row.SourceLineNumbers, "IsolatedComponent", outputInstallerVersion));
715 + this.Messaging.Write(WixWarnings.TableIncompatibleWithInstallerVersion(row.SourceLineNumbers, "IsolatedComponent", outputInstallerVersion));
716 }
717 }
718 }
@@ -1095,7 +727,7 @@ namespace WixToolset.Core
727 {
728 if (null != row[12] || null != row[13] || null != row[14] || null != row[15])
729 {
1098 - this.OnMessage(WixWarnings.ColumnsIncompatibleWithInstallerVersion(row.SourceLineNumbers, "Shortcut", outputInstallerVersion));
730 + this.Messaging.Write(WixWarnings.ColumnsIncompatibleWithInstallerVersion(row.SourceLineNumbers, "Shortcut", outputInstallerVersion));
731 }
732 }
733 }
@@ -1103,15 +735,6 @@ namespace WixToolset.Core
735 }
736 #endif
737
1106 - /// <summary>
1107 - /// Sends a message to the message delegate if there is one.
1108 - /// </summary>
1109 - /// <param name="message">Message event arguments.</param>
1110 - public void OnMessage(Message message)
1111 - {
1112 - this.Messaging.Write(message);
1113 - }
1114 -
738 /// <summary>
739 /// Load the standard action symbols.
740 /// </summary>
@@ -1165,7 +788,7 @@ namespace WixToolset.Core
788 {
789 if (connection.IsExplicitPrimaryFeature)
790 {
1168 - this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), connection.PrimaryFeature ?? resolvedSection.Id));
791 + this.Messaging.Write(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), connection.PrimaryFeature ?? resolvedSection.Id));
792 continue;
793 }
794 else
@@ -1197,7 +820,7 @@ namespace WixToolset.Core
820 connection = featuresToFeatures[wixComplexReferenceRow.Child];
821 if (null != connection)
822 {
1200 - this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id)));
823 + this.Messaging.Write(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id)));
824 continue;
825 }
826
@@ -1214,7 +837,7 @@ namespace WixToolset.Core
837 {
838 if (connection.IsExplicitPrimaryFeature)
839 {
1217 - this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id)));
840 + this.Messaging.Write(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id)));
841 continue;
842 }
843 else
@@ -1241,7 +864,7 @@ namespace WixToolset.Core
864 case ComplexReferenceChildType.Component:
865 if (componentsToModules.ContainsKey(wixComplexReferenceRow.Child))
866 {
1244 - this.OnMessage(ErrorMessages.ComponentReferencedTwice(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.Child));
867 + this.Messaging.Write(ErrorMessages.ComponentReferencedTwice(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.Child));
868 continue;
869 }
870 else
@@ -1285,7 +908,7 @@ namespace WixToolset.Core
908 connection = featuresToFeatures[wixComplexReferenceRow.Child];
909 if (null != connection)
910 {
1288 - this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id)));
911 + this.Messaging.Write(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id)));
912 continue;
913 }
914
@@ -1470,7 +1093,7 @@ namespace WixToolset.Core
1093 // way up to present the loop as a directed graph.
1094 var loop = String.Join(" -> ", loopDetector);
1095
1473 - this.OnMessage(ErrorMessages.ReferenceLoopDetected(wixComplexReferenceRow?.SourceLineNumbers, loop));
1096 + this.Messaging.Write(ErrorMessages.ReferenceLoopDetected(wixComplexReferenceRow?.SourceLineNumbers, loop));
1097
1098 // Cleanup the parentGroupsNeedingProcessing and the loopDetector just like the
1099 // exit of this method does at the end because we are exiting early.
@@ -1712,11 +1335,11 @@ namespace WixToolset.Core
1335 // display an error for the component or merge module as approrpriate
1336 if (null != multipleFeatureComponents)
1337 {
1715 - this.OnMessage(ErrorMessages.ComponentExpectedFeature(row.SourceLineNumbers, connectionId, row.Definition.Name, row.Id.Id));
1338 + this.Messaging.Write(ErrorMessages.ComponentExpectedFeature(row.SourceLineNumbers, connectionId, row.Definition.Name, row.Id.Id));
1339 }
1340 else
1341 {
1719 - this.OnMessage(ErrorMessages.MergeModuleExpectedFeature(row.SourceLineNumbers, connectionId));
1342 + this.Messaging.Write(ErrorMessages.MergeModuleExpectedFeature(row.SourceLineNumbers, connectionId));
1343 }
1344 }
1345 else
@@ -1731,7 +1354,7 @@ namespace WixToolset.Core
1354 {
1355 if (!multipleFeatureComponents.Contains(connectionId))
1356 {
1734 - this.OnMessage(WarningMessages.ImplicitComponentPrimaryFeature(connectionId));
1357 + this.Messaging.Write(WarningMessages.ImplicitComponentPrimaryFeature(connectionId));
1358
1359 // remember this component so only one warning is generated for it
1360 multipleFeatureComponents[connectionId] = null;
@@ -1739,7 +1362,7 @@ namespace WixToolset.Core
1362 }
1363 else
1364 {
1742 - this.OnMessage(WarningMessages.ImplicitMergeModulePrimaryFeature(connectionId));
1365 + this.Messaging.Write(WarningMessages.ImplicitMergeModulePrimaryFeature(connectionId));
1366 }
1367 }
1368
src/test/Example.Extension/Data/example.wir
Binary files a/src/test/Example.Extension/Data/example.wir and b/src/test/Example.Extension/Data/example.wir differ
src/test/WixToolsetTest.CoreIntegration/MsiQueryFixture.cs
+1 -1
@@ -252,7 +252,7 @@ namespace WixToolsetTest.CoreIntegration
252 }
253 }
254
255 - [Fact(Skip = "Test demonstrates failure")]
255 + [Fact]
256 public void PopulatesCustomTable1()
257 {
258 var folder = TestData.Get(@"TestData");
src/test/WixToolsetTest.CoreIntegration/WixiplFixture.cs
+1 -1
@@ -91,7 +91,7 @@ namespace WixToolsetTest.CoreIntegration
91 }
92 }
93
94 - [Fact(Skip = "Test demonstrates failure")]
94 + [Fact]
95 public void CanBuildMsiUsingExtensionLibrary()
96 {
97 var folder = TestData.Get(@"TestData\Wixipl");