Additional IR updates
Rob Mensching committed
Nov 11, 2017 at 01:45 UTC
9f8cb5374481b6c8a06eb2739858332350f72666
45 files changed
+2001
-2442
src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs
+92
-95
@@ -1,43 +1,44 @@
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.Databases
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.Core.Bind;
10
using WixToolset.Data;
11
using WixToolset.Data.Rows;
12
+ using WixToolset.Data.Tuples;
13
14
/// <summary>
15
/// AssignMediaCommand assigns files to cabs based on Media or MediaTemplate rows.
16
/// </summary>
15
- public class AssignMediaCommand
17
+ internal class AssignMediaCommand
18
{
17
- public AssignMediaCommand()
19
+ public AssignMediaCommand(IntermediateSection section)
20
{
21
this.CabinetNameTemplate = "Cab{0}.cab";
22
+ this.Section = section;
23
}
24
22
- public Output Output { private get; set; }
25
+ private IntermediateSection Section { get; }
26
+
27
+ public IEnumerable<FileFacade> FileFacades { private get; set; }
28
29
public bool FilesCompressed { private get; set; }
30
31
public string CabinetNameTemplate { private get; set; }
32
28
- public IEnumerable<FileFacade> FileFacades { private get; set; }
29
-
30
- public TableDefinitionCollection TableDefinitions { private get; set; }
31
-
33
/// <summary>
34
/// Gets cabinets with their file rows.
35
/// </summary>
35
- public Dictionary<MediaRow, IEnumerable<FileFacade>> FileFacadesByCabinetMedia { get; private set; }
36
+ public Dictionary<MediaTuple, IEnumerable<FileFacade>> FileFacadesByCabinetMedia { get; private set; }
37
38
/// <summary>
39
/// Get media rows.
40
/// </summary>
40
- public RowDictionary<MediaRow> MediaRows { get; private set; }
41
+ public Dictionary<int, MediaTuple> MediaRows { get; private set; }
42
43
/// <summary>
44
/// Get uncompressed file rows. This will contain file rows of File elements that are marked with compression=no.
@@ -47,42 +48,41 @@ namespace WixToolset.Core.WindowsInstaller.Databases
48
49
public void Execute()
50
{
50
- Dictionary<MediaRow, List<FileFacade>> filesByCabinetMedia = new Dictionary<MediaRow, List<FileFacade>>();
51
+ var filesByCabinetMedia = new Dictionary<MediaTuple, List<FileFacade>>();
52
52
- RowDictionary<MediaRow> mediaRows = new RowDictionary<MediaRow>();
53
+ var mediaRows = new Dictionary<int, MediaTuple>();
54
55
List<FileFacade> uncompressedFiles = new List<FileFacade>();
56
56
- MediaRow mergeModuleMediaRow = null;
57
- Table mediaTable = this.Output.Tables["Media"];
58
- Table mediaTemplateTable = this.Output.Tables["WixMediaTemplate"];
57
+ var mediaTable = this.Section.Tuples.OfType<MediaTuple>().ToList();
58
+ var mediaTemplateTable = this.Section.Tuples.OfType<WixMediaTemplateTuple>().ToList();
59
60
// If both tables are authored, it is an error.
61
- if ((mediaTemplateTable != null && mediaTemplateTable.Rows.Count > 0) && (mediaTable != null && mediaTable.Rows.Count > 1))
61
+ if ((mediaTemplateTable != null && mediaTemplateTable.Count > 0) && (mediaTable != null && mediaTable.Count > 1))
62
{
63
throw new WixException(WixErrors.MediaTableCollision(null));
64
}
65
66
// When building merge module, all the files go to "#MergeModule.CABinet".
67
- if (OutputType.Module == this.Output.Type)
67
+ if (SectionType.Module == this.Section.Type)
68
{
69
- Table mergeModuleMediaTable = new Table(this.TableDefinitions["Media"]);
70
- mergeModuleMediaRow = (MediaRow)mergeModuleMediaTable.CreateRow(null);
69
+ var mergeModuleMediaRow = new MediaTuple();
70
mergeModuleMediaRow.Cabinet = "#MergeModule.CABinet";
71
73
- filesByCabinetMedia.Add(mergeModuleMediaRow, new List<FileFacade>());
74
- }
72
+ this.Section.Tuples.Add(mergeModuleMediaRow);
73
76
- if (OutputType.Module == this.Output.Type || null == mediaTemplateTable)
74
+ filesByCabinetMedia.Add(mergeModuleMediaRow, new List<FileFacade>(this.FileFacades));
75
+ }
76
+ else if (null == mediaTemplateTable)
77
{
78
- this.ManuallyAssignFiles(mediaTable, mergeModuleMediaRow, this.FileFacades, filesByCabinetMedia, mediaRows, uncompressedFiles);
78
+ this.ManuallyAssignFiles(mediaTable, this.FileFacades, filesByCabinetMedia, mediaRows, uncompressedFiles);
79
}
80
else
81
{
82
this.AutoAssignFiles(mediaTable, this.FileFacades, filesByCabinetMedia, mediaRows, uncompressedFiles);
83
}
84
85
- this.FileFacadesByCabinetMedia = new Dictionary<MediaRow, IEnumerable<FileFacade>>();
85
+ this.FileFacadesByCabinetMedia = new Dictionary<MediaTuple, IEnumerable<FileFacade>>();
86
87
foreach (var mediaRowWithFiles in filesByCabinetMedia)
88
{
@@ -98,7 +98,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
98
/// Assign files to cabinets based on MediaTemplate authoring.
99
/// </summary>
100
/// <param name="fileFacades">FileRowCollection</param>
101
- private void AutoAssignFiles(Table mediaTable, IEnumerable<FileFacade> fileFacades, Dictionary<MediaRow, List<FileFacade>> filesByCabinetMedia, RowDictionary<MediaRow> mediaRows, List<FileFacade> uncompressedFiles)
101
+ private void AutoAssignFiles(List<MediaTuple> mediaTable, IEnumerable<FileFacade> fileFacades, Dictionary<MediaTuple, List<FileFacade>> filesByCabinetMedia, Dictionary<int, MediaTuple> mediaRows, List<FileFacade> uncompressedFiles)
102
{
103
const int MaxCabIndex = 999;
104
@@ -107,13 +107,19 @@ namespace WixToolset.Core.WindowsInstaller.Databases
107
int maxPreCabSizeInMB = 0;
108
int currentCabIndex = 0;
109
110
- MediaRow currentMediaRow = null;
110
+ MediaTuple currentMediaRow = null;
111
112
- Table mediaTemplateTable = this.Output.Tables["WixMediaTemplate"];
112
+ var mediaTemplateTable = this.Section.Tuples.OfType<WixMediaTemplateTuple>();
113
+
114
+ // Remove all previous media tuples since they will be replaced with
115
+ // media template.
116
+ foreach (var mediaTuple in mediaTable)
117
+ {
118
+ this.Section.Tuples.Remove(mediaTuple);
119
+ }
120
121
// Auto assign files to cabinets based on maximum uncompressed media size
115
- mediaTable.Rows.Clear();
116
- WixMediaTemplateRow mediaTemplateRow = (WixMediaTemplateRow)mediaTemplateTable.Rows[0];
122
+ var mediaTemplateRow = mediaTemplateTable.Single();
123
124
if (!String.IsNullOrEmpty(mediaTemplateRow.CabinetTemplate))
125
{
@@ -149,9 +155,9 @@ namespace WixToolset.Core.WindowsInstaller.Databases
155
{
156
// When building a product, if the current file is not to be compressed or if
157
// the package set not to be compressed, don't cab it.
152
- if (OutputType.Product == this.Output.Type &&
153
- (!facade.File.Compressed.Value ||
154
- (!facade.File.Compressed.HasValue && !this.FilesCompressed)))
158
+ if (SectionType.Product == this.Section.Type &&
159
+ ((facade.File.Compressed.HasValue && !facade.File.Compressed.Value) ||
160
+ (!facade.File.Compressed.HasValue && !this.FilesCompressed)))
161
{
162
uncompressedFiles.Add(facade);
163
continue;
@@ -172,8 +178,8 @@ namespace WixToolset.Core.WindowsInstaller.Databases
178
if (currentPreCabSize > maxPreCabSizeInBytes)
179
{
180
// Overflow due to current file
175
- currentMediaRow = this.AddMediaRow(mediaTemplateRow, mediaTable, ++currentCabIndex);
176
- mediaRows.Add(currentMediaRow);
181
+ currentMediaRow = this.AddMediaRow(mediaTemplateRow, ++currentCabIndex);
182
+ mediaRows.Add(currentMediaRow.DiskId, currentMediaRow);
183
filesByCabinetMedia.Add(currentMediaRow, new List<FileFacade>());
184
185
List<FileFacade> cabinetFileRows = filesByCabinetMedia[currentMediaRow];
@@ -188,8 +194,8 @@ namespace WixToolset.Core.WindowsInstaller.Databases
194
if (currentMediaRow == null)
195
{
196
// Create new cab and MediaRow
191
- currentMediaRow = this.AddMediaRow(mediaTemplateRow, mediaTable, ++currentCabIndex);
192
- mediaRows.Add(currentMediaRow);
197
+ currentMediaRow = this.AddMediaRow(mediaTemplateRow, ++currentCabIndex);
198
+ mediaRows.Add(currentMediaRow.DiskId, currentMediaRow);
199
filesByCabinetMedia.Add(currentMediaRow, new List<FileFacade>());
200
}
201
@@ -201,11 +207,13 @@ namespace WixToolset.Core.WindowsInstaller.Databases
207
}
208
209
// If there are uncompressed files and no MediaRow, create a default one.
204
- if (uncompressedFiles.Count > 0 && mediaTable.Rows.Count == 0)
210
+ if (uncompressedFiles.Count > 0 && !this.Section.Tuples.OfType<MediaTuple>().Any())
211
{
206
- MediaRow defaultMediaRow = (MediaRow)mediaTable.CreateRow(null);
212
+ var defaultMediaRow = new MediaTuple(null, new Identifier(1, AccessModifier.Private));
213
defaultMediaRow.DiskId = 1;
208
- mediaRows.Add(defaultMediaRow);
214
+
215
+ mediaRows.Add(1, defaultMediaRow);
216
+ this.Section.Tuples.Add(defaultMediaRow);
217
}
218
}
219
@@ -213,79 +221,65 @@ namespace WixToolset.Core.WindowsInstaller.Databases
221
/// Assign files to cabinets based on Media authoring.
222
/// </summary>
223
/// <param name="mediaTable"></param>
216
- /// <param name="mergeModuleMediaRow"></param>
224
/// <param name="fileFacades"></param>
218
- private void ManuallyAssignFiles(Table mediaTable, MediaRow mergeModuleMediaRow, IEnumerable<FileFacade> fileFacades, Dictionary<MediaRow, List<FileFacade>> filesByCabinetMedia, RowDictionary<MediaRow> mediaRows, List<FileFacade> uncompressedFiles)
225
+ private void ManuallyAssignFiles(List<MediaTuple> mediaTable, IEnumerable<FileFacade> fileFacades, Dictionary<MediaTuple, List<FileFacade>> filesByCabinetMedia, Dictionary<int, MediaTuple> mediaRows, List<FileFacade> uncompressedFiles)
226
{
220
- if (OutputType.Module != this.Output.Type)
227
+ if (mediaTable.Any())
228
{
222
- if (null != mediaTable)
229
+ var cabinetMediaRows = new Dictionary<string, MediaTuple>(StringComparer.OrdinalIgnoreCase);
230
+ foreach (var mediaRow in mediaTable)
231
{
224
- Dictionary<string, MediaRow> cabinetMediaRows = new Dictionary<string, MediaRow>(StringComparer.InvariantCultureIgnoreCase);
225
- foreach (MediaRow mediaRow in mediaTable.Rows)
232
+ // If the Media row has a cabinet, make sure it is unique across all Media rows.
233
+ if (!String.IsNullOrEmpty(mediaRow.Cabinet))
234
{
227
- // If the Media row has a cabinet, make sure it is unique across all Media rows.
228
- if (!String.IsNullOrEmpty(mediaRow.Cabinet))
235
+ if (cabinetMediaRows.TryGetValue(mediaRow.Cabinet, out var existingRow))
236
{
230
- MediaRow existingRow;
231
- if (cabinetMediaRows.TryGetValue(mediaRow.Cabinet, out existingRow))
232
- {
233
- Messaging.Instance.OnMessage(WixErrors.DuplicateCabinetName(mediaRow.SourceLineNumbers, mediaRow.Cabinet));
234
- Messaging.Instance.OnMessage(WixErrors.DuplicateCabinetName2(existingRow.SourceLineNumbers, existingRow.Cabinet));
235
- }
236
- else
237
- {
238
- cabinetMediaRows.Add(mediaRow.Cabinet, mediaRow);
239
- }
237
+ Messaging.Instance.OnMessage(WixErrors.DuplicateCabinetName(mediaRow.SourceLineNumbers, mediaRow.Cabinet));
238
+ Messaging.Instance.OnMessage(WixErrors.DuplicateCabinetName2(existingRow.SourceLineNumbers, existingRow.Cabinet));
239
+ }
240
+ else
241
+ {
242
+ cabinetMediaRows.Add(mediaRow.Cabinet, mediaRow);
243
}
241
-
242
- mediaRows.Add(mediaRow);
244
}
245
+
246
+ mediaRows.Add(mediaRow.DiskId, mediaRow);
247
}
248
+ }
249
246
- foreach (MediaRow mediaRow in mediaRows.Values)
250
+ foreach (var mediaRow in mediaRows.Values)
251
+ {
252
+ if (null != mediaRow.Cabinet)
253
{
248
- if (null != mediaRow.Cabinet)
249
- {
250
- filesByCabinetMedia.Add(mediaRow, new List<FileFacade>());
251
- }
254
+ filesByCabinetMedia.Add(mediaRow, new List<FileFacade>());
255
}
256
}
257
258
foreach (FileFacade facade in fileFacades)
259
{
257
- if (OutputType.Module == this.Output.Type)
260
+ if (!mediaRows.TryGetValue(facade.WixFile.DiskId, out var mediaRow))
261
{
259
- filesByCabinetMedia[mergeModuleMediaRow].Add(facade);
262
+ Messaging.Instance.OnMessage(WixErrors.MissingMedia(facade.File.SourceLineNumbers, facade.WixFile.DiskId));
263
+ continue;
264
}
261
- else
262
- {
263
- MediaRow mediaRow;
264
- if (!mediaRows.TryGetValue(facade.WixFile.DiskId.ToString(CultureInfo.InvariantCulture), out mediaRow))
265
- {
266
- Messaging.Instance.OnMessage(WixErrors.MissingMedia(facade.File.SourceLineNumbers, facade.WixFile.DiskId));
267
- continue;
268
- }
265
270
- // When building a product, if the current file is not to be compressed or if
271
- // the package set not to be compressed, don't cab it.
272
- if (OutputType.Product == this.Output.Type &&
273
- (!facade.File.Compressed.Value ||
274
- (!facade.File.Compressed.HasValue && !this.FilesCompressed)))
266
+ // When building a product, if the current file is not to be compressed or if
267
+ // the package set not to be compressed, don't cab it.
268
+ if (SectionType.Product == this.Section.Type &&
269
+ (!facade.File.Compressed.Value ||
270
+ (!facade.File.Compressed.HasValue && !this.FilesCompressed)))
271
+ {
272
+ uncompressedFiles.Add(facade);
273
+ }
274
+ else // file is marked compressed.
275
+ {
276
+ if (filesByCabinetMedia.TryGetValue(mediaRow, out var cabinetFiles))
277
{
276
- uncompressedFiles.Add(facade);
278
+ cabinetFiles.Add(facade);
279
}
278
- else // file is marked compressed.
280
+ else
281
{
280
- List<FileFacade> cabinetFiles;
281
- if (filesByCabinetMedia.TryGetValue(mediaRow, out cabinetFiles))
282
- {
283
- cabinetFiles.Add(facade);
284
- }
285
- else
286
- {
287
- Messaging.Instance.OnMessage(WixErrors.ExpectedMediaCabinet(facade.File.SourceLineNumbers, facade.File.File, facade.WixFile.DiskId));
288
- }
282
+ Messaging.Instance.OnMessage(WixErrors.ExpectedMediaCabinet(facade.File.SourceLineNumbers, facade.File.File, facade.WixFile.DiskId));
283
}
284
}
285
}
@@ -297,17 +291,20 @@ namespace WixToolset.Core.WindowsInstaller.Databases
291
/// <param name="mediaTable"></param>
292
/// <param name="cabIndex"></param>
293
/// <returns></returns>
300
- private MediaRow AddMediaRow(WixMediaTemplateRow mediaTemplateRow, Table mediaTable, int cabIndex)
294
+ private MediaTuple AddMediaRow(WixMediaTemplateTuple mediaTemplateRow, int cabIndex)
295
{
302
- MediaRow currentMediaRow = (MediaRow)mediaTable.CreateRow(mediaTemplateRow.SourceLineNumbers);
296
+ var currentMediaRow = new MediaTuple(mediaTemplateRow.SourceLineNumbers, new Identifier(cabIndex, AccessModifier.Private));
297
currentMediaRow.DiskId = cabIndex;
298
currentMediaRow.Cabinet = String.Format(CultureInfo.InvariantCulture, this.CabinetNameTemplate, cabIndex);
299
306
- Table wixMediaTable = this.Output.EnsureTable(this.TableDefinitions["WixMedia"]);
307
- WixMediaRow row = (WixMediaRow)wixMediaTable.CreateRow(mediaTemplateRow.SourceLineNumbers);
308
- row.DiskId = cabIndex;
300
+ this.Section.Tuples.Add(currentMediaRow);
301
+
302
+ var row = new WixMediaTuple(mediaTemplateRow.SourceLineNumbers, new Identifier(cabIndex, AccessModifier.Private));
303
+ row.DiskId_ = cabIndex;
304
row.CompressionLevel = mediaTemplateRow.CompressionLevel;
305
306
+ this.Section.Tuples.Add(row);
307
+
308
return currentMediaRow;
309
}
310
}
src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+224
-515
@@ -3,21 +3,15 @@
3
namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
- using System.Collections;
6
using System.Collections.Generic;
8
- using System.Diagnostics;
9
- using System.Globalization;
7
using System.IO;
8
using System.Linq;
12
- using WixToolset.Bind;
9
using WixToolset.Core.Bind;
14
- using WixToolset.Core.WindowsInstaller.Databases;
10
using WixToolset.Data;
11
using WixToolset.Data.Bind;
17
- using WixToolset.Data.Rows;
12
+ using WixToolset.Data.Tuples;
13
using WixToolset.Extensibility;
14
using WixToolset.Extensibility.Services;
20
- using WixToolset.Msi;
15
16
/// <summary>
17
/// Binds a databse.
@@ -25,11 +19,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
19
internal class BindDatabaseCommand
20
{
21
// As outlined in RFC 4122, this is our namespace for generating name-based (version 3) UUIDs.
28
- private static readonly Guid WixComponentGuidNamespace = new Guid("{3064E5C6-FB63-4FE9-AC49-E446A792EFA5}");
22
+ internal static readonly Guid WixComponentGuidNamespace = new Guid("{3064E5C6-FB63-4FE9-AC49-E446A792EFA5}");
23
24
public BindDatabaseCommand(IBindContext context, Validator validator)
25
{
32
- this.TableDefinitions = WindowsInstallerStandard.GetTableDefinitions();
26
+ this.TableDefinitions = WindowsInstallerStandardInternal.GetTableDefinitions();
27
28
this.BindPaths = context.BindPaths;
29
this.CabbingThreadCount = context.CabbingThreadCount;
@@ -73,8 +67,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
67
68
private Intermediate Intermediate { get; }
69
76
- private Output Output { get; }
77
-
70
private string OutputPath { get; }
71
72
private bool SuppressAddingValidationRows { get; }
@@ -95,22 +87,16 @@ namespace WixToolset.Core.WindowsInstaller.Bind
87
88
public void Execute()
89
{
98
- this.Intermediate.Save(this.OutputPath);
99
-#if FINISH
100
- List<FileTransfer> fileTransfers = new List<FileTransfer>();
90
+ var section = this.Intermediate.Sections.Single();
91
102
- HashSet<string> suppressedTableNames = new HashSet<string>();
92
+ var fileTransfers = new List<FileTransfer>();
93
104
- // If there are any fields to resolve later, create the cache to populate during bind.
105
- IDictionary<string, string> variableCache = null;
106
- if (this.DelayedFields.Any())
107
- {
108
- variableCache = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
109
- }
94
+ var suppressedTableNames = new HashSet<string>();
95
111
- this.LocalizeUI(this.Output.Tables);
96
+ // If there are any fields to resolve later, create the cache to populate during bind.
97
+ var variableCache = this.DelayedFields.Any() ? new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase) : null;
98
113
- this.Output = CreateOutputFromIR(this.Intermediate);
99
+ this.LocalizeUI(section);
100
101
// Process the summary information table before the other tables.
102
bool compressed;
@@ -118,8 +104,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
104
int installerVersion;
105
string modularizationGuid;
106
{
121
- BindSummaryInfoCommand command = new BindSummaryInfoCommand();
122
- command.Output = this.Output;
107
+ var command = new BindSummaryInfoCommand(section);
108
command.Execute();
109
110
compressed = command.Compressed;
@@ -128,42 +113,61 @@ namespace WixToolset.Core.WindowsInstaller.Bind
113
modularizationGuid = command.ModularizationGuid;
114
}
115
131
- // Stop processing if an error previously occurred.
132
- if (Messaging.Instance.EncounteredError)
133
- {
134
- return;
135
- }
136
-
137
- // Modularize identifiers and add tables with real streams to the import tables.
138
- if (OutputType.Module == this.Output.Type)
116
+ // Add binder variables for all properties.
117
+ if (SectionType.Product == section.Type || variableCache != null)
118
{
140
- // Gather all the suppress modularization identifiers
141
- HashSet<string> suppressModularizationIdentifiers = null;
142
- Table wixSuppressModularizationTable = this.Output.Tables["WixSuppressModularization"];
143
- if (null != wixSuppressModularizationTable)
119
+ foreach (var propertyRow in section.Tuples.OfType<PropertyTuple>())
120
{
145
- suppressModularizationIdentifiers = new HashSet<string>(wixSuppressModularizationTable.Rows.Select(row => (string)row[0]));
146
- }
121
+ // Set the ProductCode if it is to be generated.
122
+ if ("ProductCode".Equals(propertyRow.Property, StringComparison.Ordinal) && "*".Equals(propertyRow.Value, StringComparison.Ordinal))
123
+ {
124
+ propertyRow.Value = Common.GenerateGuid();
125
148
- foreach (Table table in this.Output.Tables)
149
- {
150
- table.Modularize(modularizationGuid, suppressModularizationIdentifiers);
126
+#if TODO_FIX_INSTANCE_TRANSFORM
127
+ // Update the target ProductCode in any instance transforms.
128
+ foreach (SubStorage subStorage in this.Output.SubStorages)
129
+ {
130
+ Output subStorageOutput = subStorage.Data;
131
+ if (OutputType.Transform != subStorageOutput.Type)
132
+ {
133
+ continue;
134
+ }
135
+
136
+ Table instanceSummaryInformationTable = subStorageOutput.Tables["_SummaryInformation"];
137
+ foreach (Row row in instanceSummaryInformationTable.Rows)
138
+ {
139
+ if ((int)SummaryInformation.Transform.ProductCodes == row.FieldAsInteger(0))
140
+ {
141
+ row[1] = row.FieldAsString(1).Replace("*", propertyRow.Value);
142
+ break;
143
+ }
144
+ }
145
+ }
146
+#endif
147
+ }
148
+
149
+ // Add the property name and value to the variableCache.
150
+ if (variableCache != null)
151
+ {
152
+ var key = String.Concat("property.", propertyRow.Property);
153
+ variableCache[key] = propertyRow.Value;
154
+ }
155
}
156
}
157
154
- // This must occur after all variables and source paths have been resolved and after modularization.
155
- List<FileFacade> fileFacades;
158
+ // Sequence all the actions.
159
{
157
- GetFileFacadesCommand command = new GetFileFacadesCommand();
158
- command.FileTable = this.Output.Tables["File"];
159
- command.WixFileTable = this.Output.Tables["WixFile"];
160
- command.WixDeltaPatchFileTable = this.Output.Tables["WixDeltaPatchFile"];
161
- command.WixDeltaPatchSymbolPathsTable = this.Output.Tables["WixDeltaPatchSymbolPaths"];
160
+ var command = new SequenceActionsCommand(section);
161
+ command.Messaging = Messaging.Instance;
162
command.Execute();
163
+ }
164
164
- fileFacades = command.FileFacades;
165
+ {
166
+ var command = new CreateSpecialPropertiesCommand(section);
167
+ command.Execute();
168
}
169
170
+#if TODO_FINISH_PATCH
171
////if (OutputType.Patch == this.Output.Type)
172
////{
173
//// foreach (SubStorage substorage in this.Output.SubStorages)
@@ -183,87 +187,72 @@ namespace WixToolset.Core.WindowsInstaller.Bind
187
//// this.MergeUnrealTables(transform.Tables);
188
//// }
189
////}
186
-
187
- {
188
- CreateSpecialPropertiesCommand command = new CreateSpecialPropertiesCommand();
189
- command.PropertyTable = this.Output.Tables["Property"];
190
- command.WixPropertyTable = this.Output.Tables["WixProperty"];
191
- command.Execute();
192
- }
190
+#endif
191
192
if (Messaging.Instance.EncounteredError)
193
{
194
return;
195
}
196
199
- // Add binder variables for all properties.
200
- Table propertyTable = this.Output.Tables["Property"];
201
- if (null != propertyTable)
197
+ Messaging.Instance.OnMessage(WixVerboses.UpdatingFileInformation());
198
+
199
+ // This must occur after all variables and source paths have been resolved.
200
+ List<FileFacade> fileFacades;
201
{
203
- foreach (PropertyRow propertyRow in propertyTable.Rows)
204
- {
205
- // Set the ProductCode if it is to be generated.
206
- if (OutputType.Product == this.Output.Type && "ProductCode".Equals(propertyRow.Property, StringComparison.Ordinal) && "*".Equals(propertyRow.Value, StringComparison.Ordinal))
207
- {
208
- propertyRow.Value = Common.GenerateGuid();
202
+ var command = new GetFileFacadesCommand(section);
203
+ command.Execute();
204
210
- // Update the target ProductCode in any instance transforms.
211
- foreach (SubStorage subStorage in this.Output.SubStorages)
212
- {
213
- Output subStorageOutput = subStorage.Data;
214
- if (OutputType.Transform != subStorageOutput.Type)
215
- {
216
- continue;
217
- }
205
+ fileFacades = command.FileFacades;
206
+ }
207
219
- Table instanceSummaryInformationTable = subStorageOutput.Tables["_SummaryInformation"];
220
- foreach (Row row in instanceSummaryInformationTable.Rows)
221
- {
222
- if ((int)SummaryInformation.Transform.ProductCodes == row.FieldAsInteger(0))
223
- {
224
- row[1] = row.FieldAsString(1).Replace("*", propertyRow.Value);
225
- break;
226
- }
227
- }
228
- }
229
- }
208
+ // Extract files that come from binary .wixlibs and WixExtensions (this does not extract files from merge modules).
209
+ {
210
+ var command = new ExtractEmbeddedFilesCommand(this.ExpectedEmbeddedFiles);
211
+ command.Execute();
212
+ }
213
231
- // Add the property name and value to the variableCache.
232
- if (null != variableCache)
233
- {
234
- string key = String.Concat("property.", Common.Demodularize(this.Output.Type, modularizationGuid, propertyRow.Property));
235
- variableCache[key] = propertyRow.Value;
236
- }
237
- }
214
+ // Gather information about files that did not come from merge modules (i.e. rows with a reference to the File table).
215
+ {
216
+ var command = new UpdateFileFacadesCommand(section);
217
+ command.FileFacades = fileFacades;
218
+ command.UpdateFileFacades = fileFacades.Where(f => !f.FromModule);
219
+ command.OverwriteHash = true;
220
+ command.TableDefinitions = this.TableDefinitions;
221
+ command.VariableCache = variableCache;
222
+ command.Execute();
223
}
224
240
- // Extract files that come from cabinet files (this does not extract files from merge modules).
225
+ // Now that the variable cache is populated, resolve any delayed fields.
226
+ if (this.DelayedFields.Any())
227
{
242
- ExtractEmbeddedFilesCommand command = new ExtractEmbeddedFilesCommand();
243
- command.FilesWithEmbeddedFiles = this.ExpectedEmbeddedFiles;
228
+ var command = new ResolveDelayedFieldsCommand(this.DelayedFields, variableCache);
229
command.Execute();
230
}
231
247
- if (OutputType.Product == this.Output.Type)
232
+ // Set generated component guids.
233
+ {
234
+ var command = new CalculateComponentGuids(section);
235
+ command.Execute();
236
+ }
237
+
238
+ if (SectionType.Product == section.Type)
239
{
240
// Retrieve files and their information from merge modules.
250
- Table wixMergeTable = this.Output.Tables["WixMerge"];
241
+ var wixMergeTuples = section.Tuples.OfType<WixMergeTuple>().ToList();
242
252
- if (null != wixMergeTable)
243
+ if (wixMergeTuples.Any())
244
{
254
- ExtractMergeModuleFilesCommand command = new ExtractMergeModuleFilesCommand();
245
+ var command = new ExtractMergeModuleFilesCommand(section, wixMergeTuples);
246
command.FileFacades = fileFacades;
256
- command.FileTable = this.Output.Tables["File"];
257
- command.WixFileTable = this.Output.Tables["WixFile"];
258
- command.WixMergeTable = wixMergeTable;
247
command.OutputInstallerVersion = installerVersion;
248
command.SuppressLayout = this.SuppressLayout;
261
- command.TempFilesLocation = this.IntermediateFolder;
249
+ command.IntermediateFolder = this.IntermediateFolder;
250
command.Execute();
251
252
fileFacades.AddRange(command.MergeModulesFileFacades);
253
}
254
}
255
+#if TODO_FINISH_PATCH
256
else if (OutputType.Patch == this.Output.Type)
257
{
258
// Merge transform data into the output object.
@@ -271,6 +260,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
260
261
fileFacades.AddRange(filesFromTransform);
262
}
263
+#endif
264
265
// stop processing if an error previously occurred
266
if (Messaging.Instance.EncounteredError)
@@ -278,51 +268,19 @@ namespace WixToolset.Core.WindowsInstaller.Bind
268
return;
269
}
270
281
- Messaging.Instance.OnMessage(WixVerboses.UpdatingFileInformation());
282
-
283
- // Gather information about files that did not come from merge modules (i.e. rows with a reference to the File table).
284
- {
285
- UpdateFileFacadesCommand command = new UpdateFileFacadesCommand();
286
- command.FileFacades = fileFacades;
287
- command.UpdateFileFacades = fileFacades.Where(f => !f.FromModule);
288
- command.ModularizationGuid = modularizationGuid;
289
- command.Output = this.Output;
290
- command.OverwriteHash = true;
291
- command.TableDefinitions = this.TableDefinitions;
292
- command.VariableCache = variableCache;
293
- command.Execute();
294
- }
295
-
296
- // Set generated component guids.
297
- this.SetComponentGuids(this.Output);
298
-
271
+#if TODO_FIX_INSTANCE_TRANSFORM
272
// With the Component Guids set now we can create instance transforms.
273
this.CreateInstanceTransforms(this.Output);
301
-
302
- this.ValidateComponentGuids(this.Output);
303
-
304
- this.UpdateControlText(this.Output);
305
-
306
- if (this.DelayedFields.Any())
307
- {
308
- ResolveDelayedFieldsCommand command = new ResolveDelayedFieldsCommand();
309
- command.OutputType = this.Output.Type;
310
- command.DelayedFields = this.DelayedFields;
311
- command.ModularizationGuid = null;
312
- command.VariableCache = variableCache;
313
- command.Execute();
314
- }
274
+#endif
275
276
// Assign files to media.
317
- RowDictionary<MediaRow> assignedMediaRows;
318
- Dictionary<MediaRow, IEnumerable<FileFacade>> filesByCabinetMedia;
277
+ Dictionary<int, MediaTuple> assignedMediaRows;
278
+ Dictionary<MediaTuple, IEnumerable<FileFacade>> filesByCabinetMedia;
279
IEnumerable<FileFacade> uncompressedFiles;
280
{
321
- AssignMediaCommand command = new AssignMediaCommand();
322
- command.FilesCompressed = compressed;
281
+ var command = new AssignMediaCommand(section);
282
command.FileFacades = fileFacades;
324
- command.Output = this.Output;
325
- command.TableDefinitions = this.TableDefinitions;
283
+ command.FilesCompressed = compressed;
284
command.Execute();
285
286
assignedMediaRows = command.MediaRows;
@@ -330,15 +288,40 @@ namespace WixToolset.Core.WindowsInstaller.Bind
288
uncompressedFiles = command.UncompressedFileFacades;
289
}
290
333
- // Update file sequence.
334
- this.UpdateMediaSequences(this.Output.Type, fileFacades, assignedMediaRows);
335
-
291
// stop processing if an error previously occurred
292
if (Messaging.Instance.EncounteredError)
293
{
294
return;
295
}
296
297
+ // Try to put as much above here as possible, updating the IR is better.
298
+ Output output;
299
+ {
300
+ var command = new CreateOutputFromIRCommand(section, this.TableDefinitions);
301
+ command.Execute();
302
+
303
+ output = command.Output;
304
+ }
305
+
306
+ // Update file sequence.
307
+ {
308
+ var command = new UpdateMediaSequencesCommand(output, fileFacades, assignedMediaRows);
309
+ command.Execute();
310
+ }
311
+
312
+ // Modularize identifiers and add tables with real streams to the import tables.
313
+ if (OutputType.Module == output.Type)
314
+ {
315
+ // Gather all the suppress modularization identifiers
316
+ var suppressModularizationIdentifiers = new HashSet<string>(section.Tuples.OfType<WixSuppressModularizationTuple>().Select(s => s.WixSuppressModularization));
317
+
318
+ foreach (var table in output.Tables)
319
+ {
320
+ table.Modularize(modularizationGuid, suppressModularizationIdentifiers);
321
+ }
322
+ }
323
+
324
+#if TODO_FINISH_UPDATE
325
// Extended binder extensions can be called now that fields are resolved.
326
{
327
Table updatedFiles = this.Output.EnsureTable(this.TableDefinitions["WixBindUpdatedFiles"]);
@@ -372,27 +355,27 @@ namespace WixToolset.Core.WindowsInstaller.Bind
355
command.Execute();
356
}
357
}
358
+#endif
359
376
- // stop processing if an error previously occurred
360
+ // Stop processing if an error previously occurred.
361
if (Messaging.Instance.EncounteredError)
362
{
363
return;
364
}
365
366
+ // Ensure the intermediate folder is created since delta patches will be
367
+ // created there.
368
Directory.CreateDirectory(this.IntermediateFolder);
369
384
- if (OutputType.Patch == this.Output.Type && this.DeltaBinaryPatch)
370
+ if (SectionType.Patch == section.Type && this.DeltaBinaryPatch)
371
{
386
- CreateDeltaPatchesCommand command = new CreateDeltaPatchesCommand();
387
- command.FileFacades = fileFacades;
388
- command.WixPatchIdTable = this.Output.Tables["WixPatchId"];
389
- command.TempFilesLocation = this.IntermediateFolder;
372
+ var command = new CreateDeltaPatchesCommand(fileFacades, this.IntermediateFolder, section.Tuples.OfType<WixPatchIdTuple>().FirstOrDefault());
373
command.Execute();
374
}
375
376
// create cabinet files and process uncompressed files
377
string layoutDirectory = Path.GetDirectoryName(this.OutputPath);
395
- if (!this.SuppressLayout || OutputType.Module == this.Output.Type)
378
+ if (!this.SuppressLayout || OutputType.Module == output.Type)
379
{
380
Messaging.Instance.OnMessage(WixVerboses.CreatingCabinetFiles());
381
@@ -400,7 +383,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
383
command.CabbingThreadCount = this.CabbingThreadCount;
384
command.CabCachePath = this.CabCachePath;
385
command.DefaultCompressionLevel = this.DefaultCompressionLevel;
403
- command.Output = this.Output;
386
+ command.Output = output;
387
command.BackendExtensions = this.BackendExtensions;
388
command.LayoutDirectory = layoutDirectory;
389
command.Compressed = compressed;
@@ -408,39 +391,35 @@ namespace WixToolset.Core.WindowsInstaller.Bind
391
command.ResolveMedia = this.ResolveMedia;
392
command.TableDefinitions = this.TableDefinitions;
393
command.TempFilesLocation = this.IntermediateFolder;
411
- command.WixMediaTable = this.Output.Tables["WixMedia"];
394
+ command.WixMediaTable = output.Tables["WixMedia"];
395
command.Execute();
396
397
fileTransfers.AddRange(command.FileTransfers);
398
}
399
400
+#if TODO_FINISH_PATCH
401
if (OutputType.Patch == this.Output.Type)
402
{
403
// copy output data back into the transforms
404
this.CopyToTransformData(this.Output);
405
}
406
+#endif
407
423
- // stop processing if an error previously occurred
424
- if (Messaging.Instance.EncounteredError)
425
- {
426
- return;
427
- }
428
-
429
- // add back suppressed tables which must be present prior to merging in modules
430
- if (OutputType.Product == this.Output.Type)
408
+ // Add back suppressed tables which must be present prior to merging in modules.
409
+ if (OutputType.Product == output.Type)
410
{
432
- Table wixMergeTable = this.Output.Tables["WixMerge"];
411
+ Table wixMergeTable = output.Tables["WixMerge"];
412
413
if (null != wixMergeTable && 0 < wixMergeTable.Rows.Count)
414
{
415
foreach (SequenceTable sequence in Enum.GetValues(typeof(SequenceTable)))
416
{
417
string sequenceTableName = sequence.ToString();
439
- Table sequenceTable = this.Output.Tables[sequenceTableName];
418
+ Table sequenceTable = output.Tables[sequenceTableName];
419
420
if (null == sequenceTable)
421
{
443
- sequenceTable = this.Output.EnsureTable(this.TableDefinitions[sequenceTableName]);
422
+ sequenceTable = output.EnsureTable(this.TableDefinitions[sequenceTableName]);
423
}
424
425
if (0 == sequenceTable.Rows.Count)
@@ -456,67 +435,59 @@ namespace WixToolset.Core.WindowsInstaller.Bind
435
// extension.PostBind(this.Context);
436
//}
437
459
- // generate database file
438
+ this.ValidateComponentGuids(output);
439
+
440
+ // stop processing if an error previously occurred
441
+ if (Messaging.Instance.EncounteredError)
442
+ {
443
+ return;
444
+ }
445
+
446
+ // Generate database file.
447
Messaging.Instance.OnMessage(WixVerboses.GeneratingDatabase());
448
string tempDatabaseFile = Path.Combine(this.IntermediateFolder, Path.GetFileName(this.OutputPath));
462
- this.GenerateDatabase(this.Output, tempDatabaseFile, false, false);
449
+ this.GenerateDatabase(output, tempDatabaseFile, false, false);
450
464
- FileTransfer transfer;
465
- if (FileTransfer.TryCreate(tempDatabaseFile, this.OutputPath, true, this.Output.Type.ToString(), null, out transfer)) // note where this database needs to move in the future
451
+ if (FileTransfer.TryCreate(tempDatabaseFile, this.OutputPath, true, output.Type.ToString(), null, out var transfer)) // note where this database needs to move in the future
452
{
453
transfer.Built = true;
454
fileTransfers.Add(transfer);
455
}
456
471
- // stop processing if an error previously occurred
457
+ // Stop processing if an error previously occurred.
458
if (Messaging.Instance.EncounteredError)
459
{
460
return;
461
}
462
477
- // Output the output to a file
463
+ // Output the output to a file.
464
Pdb pdb = new Pdb();
479
- pdb.Output = this.Output;
465
+ pdb.Output = output;
466
if (!String.IsNullOrEmpty(this.PdbFile))
467
{
468
pdb.Save(this.PdbFile);
469
}
470
471
// Merge modules.
486
- if (OutputType.Product == this.Output.Type)
472
+ if (OutputType.Product == output.Type)
473
{
474
Messaging.Instance.OnMessage(WixVerboses.MergingModules());
475
490
- MergeModulesCommand command = new MergeModulesCommand();
476
+ var command = new MergeModulesCommand();
477
command.FileFacades = fileFacades;
492
- command.Output = this.Output;
478
+ command.Output = output;
479
command.OutputPath = tempDatabaseFile;
480
command.SuppressedTableNames = suppressedTableNames;
481
command.Execute();
496
-
497
- // stop processing if an error previously occurred
498
- if (Messaging.Instance.EncounteredError)
499
- {
500
- return;
501
- }
482
}
483
504
- // inspect the MSI prior to running ICEs
505
- //InspectorCore inspectorCore = new InspectorCore();
506
- //foreach (InspectorExtension inspectorExtension in this.InspectorExtensions)
507
- //{
508
- // inspectorExtension.Core = inspectorCore;
509
- // inspectorExtension.InspectDatabase(tempDatabaseFile, pdb);
510
-
511
- // inspectorExtension.Core = null; // reset.
512
- //}
513
-
484
if (Messaging.Instance.EncounteredError)
485
{
486
return;
487
}
488
519
- // validate the output if there is an MSI validator
489
+#if TODO_FINISH_VALIDATION
490
+ // Validate the output if there is an MSI validator.
491
if (null != this.Validator)
492
{
493
Stopwatch stopwatch = Stopwatch.StartNew();
@@ -537,19 +508,18 @@ namespace WixToolset.Core.WindowsInstaller.Bind
508
return;
509
}
510
}
511
+#endif
512
513
// Process uncompressed files.
514
if (!Messaging.Instance.EncounteredError && !this.SuppressLayout && uncompressedFiles.Any())
515
{
544
- var command = new ProcessUncompressedFilesCommand();
516
+ var command = new ProcessUncompressedFilesCommand(section);
517
command.Compressed = compressed;
518
command.FileFacades = uncompressedFiles;
519
command.LayoutDirectory = layoutDirectory;
520
command.LongNamesInImage = longNames;
549
- command.MediaRows = assignedMediaRows;
521
command.ResolveMedia = this.ResolveMedia;
522
command.DatabasePath = tempDatabaseFile;
552
- command.WixMediaTable = this.Output.Tables["WixMedia"];
523
command.Execute();
524
525
fileTransfers.AddRange(command.FileTransfers);
@@ -557,94 +527,92 @@ namespace WixToolset.Core.WindowsInstaller.Bind
527
528
this.FileTransfers = fileTransfers;
529
this.ContentFilePaths = fileFacades.Select(r => r.WixFile.Source).ToList();
530
+
531
+ // TODO: Eventually this gets removed
532
+ var intermediate = new Intermediate(this.Intermediate.Id, new[] { section }, this.Intermediate.Localizations.ToDictionary(l => l.Culture, StringComparer.OrdinalIgnoreCase), this.Intermediate.EmbedFilePaths);
533
+ intermediate.Save(Path.ChangeExtension(this.OutputPath, "wir"));
534
}
535
536
/// <summary>
537
/// Localize dialogs and controls.
538
/// </summary>
539
/// <param name="tables">The tables to localize.</param>
566
- private void LocalizeUI(TableIndexedCollection tables)
540
+ private void LocalizeUI(IntermediateSection section)
541
{
568
- Table dialogTable = tables["Dialog"];
569
- if (null != dialogTable)
542
+ foreach (var row in section.Tuples.OfType<DialogTuple>())
543
{
571
- foreach (Row row in dialogTable.Rows)
572
- {
573
- string dialog = (string)row[0];
544
+ string dialog = row.Dialog;
545
575
- if (this.WixVariableResolver.TryGetLocalizedControl(dialog, null, out LocalizedControl localizedControl))
546
+ if (this.WixVariableResolver.TryGetLocalizedControl(dialog, null, out LocalizedControl localizedControl))
547
+ {
548
+ if (CompilerConstants.IntegerNotSet != localizedControl.X)
549
{
577
- if (CompilerConstants.IntegerNotSet != localizedControl.X)
578
- {
579
- row[1] = localizedControl.X;
580
- }
550
+ row.HCentering = localizedControl.X;
551
+ }
552
582
- if (CompilerConstants.IntegerNotSet != localizedControl.Y)
583
- {
584
- row[2] = localizedControl.Y;
585
- }
553
+ if (CompilerConstants.IntegerNotSet != localizedControl.Y)
554
+ {
555
+ row.VCentering = localizedControl.Y;
556
+ }
557
587
- if (CompilerConstants.IntegerNotSet != localizedControl.Width)
588
- {
589
- row[3] = localizedControl.Width;
590
- }
558
+ if (CompilerConstants.IntegerNotSet != localizedControl.Width)
559
+ {
560
+ row.Width = localizedControl.Width;
561
+ }
562
592
- if (CompilerConstants.IntegerNotSet != localizedControl.Height)
593
- {
594
- row[4] = localizedControl.Height;
595
- }
563
+ if (CompilerConstants.IntegerNotSet != localizedControl.Height)
564
+ {
565
+ row.Height = localizedControl.Height;
566
+ }
567
597
- row[5] = (int)row[5] | localizedControl.Attributes;
568
+ row.Attributes = row.Attributes | localizedControl.Attributes;
569
599
- if (!String.IsNullOrEmpty(localizedControl.Text))
600
- {
601
- row[6] = localizedControl.Text;
602
- }
570
+ if (!String.IsNullOrEmpty(localizedControl.Text))
571
+ {
572
+ row.Title = localizedControl.Text;
573
}
574
}
575
}
576
607
- Table controlTable = tables["Control"];
608
- if (null != controlTable)
577
+
578
+ foreach (var row in section.Tuples.OfType<ControlTuple>())
579
{
610
- foreach (Row row in controlTable.Rows)
611
- {
612
- string dialog = (string)row[0];
613
- string control = (string)row[1];
580
+ string dialog = row.Dialog_;
581
+ string control = row.Control;
582
615
- if (this.WixVariableResolver.TryGetLocalizedControl(dialog, control, out LocalizedControl localizedControl))
583
+ if (this.WixVariableResolver.TryGetLocalizedControl(dialog, control, out LocalizedControl localizedControl))
584
+ {
585
+ if (CompilerConstants.IntegerNotSet != localizedControl.X)
586
{
617
- if (CompilerConstants.IntegerNotSet != localizedControl.X)
618
- {
619
- row[3] = localizedControl.X.ToString();
620
- }
587
+ row.X = localizedControl.X;
588
+ }
589
622
- if (CompilerConstants.IntegerNotSet != localizedControl.Y)
623
- {
624
- row[4] = localizedControl.Y.ToString();
625
- }
590
+ if (CompilerConstants.IntegerNotSet != localizedControl.Y)
591
+ {
592
+ row.Y = localizedControl.Y;
593
+ }
594
627
- if (CompilerConstants.IntegerNotSet != localizedControl.Width)
628
- {
629
- row[5] = localizedControl.Width.ToString();
630
- }
595
+ if (CompilerConstants.IntegerNotSet != localizedControl.Width)
596
+ {
597
+ row.Width = localizedControl.Width;
598
+ }
599
632
- if (CompilerConstants.IntegerNotSet != localizedControl.Height)
633
- {
634
- row[6] = localizedControl.Height.ToString();
635
- }
600
+ if (CompilerConstants.IntegerNotSet != localizedControl.Height)
601
+ {
602
+ row.Height = localizedControl.Height;
603
+ }
604
637
- row[7] = (int)row[7] | localizedControl.Attributes;
605
+ row.Attributes = row.Attributes | localizedControl.Attributes;
606
639
- if (!String.IsNullOrEmpty(localizedControl.Text))
640
- {
641
- row[9] = localizedControl.Text;
642
- }
607
+ if (!String.IsNullOrEmpty(localizedControl.Text))
608
+ {
609
+ row.Text = localizedControl.Text;
610
}
611
}
612
}
613
}
614
615
+#if TODO_FINISH_PATCH
616
/// <summary>
617
/// Copy file data between transform substorages and the patch output object
618
/// </summary>
@@ -674,269 +642,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind
642
command.TableDefinitions = this.TableDefinitions;
643
command.Execute();
644
}
645
+#endif
646
678
- private void UpdateMediaSequences(OutputType outputType, IEnumerable<FileFacade> fileFacades, RowDictionary<MediaRow> mediaRows)
679
- {
680
- // Calculate sequence numbers and media disk id layout for all file media information objects.
681
- if (OutputType.Module == outputType)
682
- {
683
- int lastSequence = 0;
684
- foreach (FileFacade facade in fileFacades) // TODO: Sort these rows directory path and component id and maybe file size or file extension and other creative ideas to get optimal install speed out of MSI.
685
- {
686
- facade.File.Sequence = ++lastSequence;
687
- }
688
- }
689
- else
690
- {
691
- int lastSequence = 0;
692
- MediaRow mediaRow = null;
693
- Dictionary<int, List<FileFacade>> patchGroups = new Dictionary<int, List<FileFacade>>();
694
-
695
- // sequence the non-patch-added files
696
- foreach (FileFacade facade in fileFacades) // TODO: Sort these rows directory path and component id and maybe file size or file extension and other creative ideas to get optimal install speed out of MSI.
697
- {
698
- if (null == mediaRow)
699
- {
700
- mediaRow = mediaRows.Get(facade.WixFile.DiskId);
701
- if (OutputType.Patch == outputType)
702
- {
703
- // patch Media cannot start at zero
704
- lastSequence = mediaRow.LastSequence;
705
- }
706
- }
707
- else if (mediaRow.DiskId != facade.WixFile.DiskId)
708
- {
709
- mediaRow.LastSequence = lastSequence;
710
- mediaRow = mediaRows.Get(facade.WixFile.DiskId);
711
- }
712
-
713
- if (0 < facade.WixFile.PatchGroup)
714
- {
715
- List<FileFacade> patchGroup = patchGroups[facade.WixFile.PatchGroup];
716
-
717
- if (null == patchGroup)
718
- {
719
- patchGroup = new List<FileFacade>();
720
- patchGroups.Add(facade.WixFile.PatchGroup, patchGroup);
721
- }
722
-
723
- patchGroup.Add(facade);
724
- }
725
- else
726
- {
727
- facade.File.Sequence = ++lastSequence;
728
- }
729
- }
730
-
731
- if (null != mediaRow)
732
- {
733
- mediaRow.LastSequence = lastSequence;
734
- mediaRow = null;
735
- }
736
-
737
- // sequence the patch-added files
738
- foreach (List<FileFacade> patchGroup in patchGroups.Values)
739
- {
740
- foreach (FileFacade facade in patchGroup)
741
- {
742
- if (null == mediaRow)
743
- {
744
- mediaRow = mediaRows.Get(facade.WixFile.DiskId);
745
- }
746
- else if (mediaRow.DiskId != facade.WixFile.DiskId)
747
- {
748
- mediaRow.LastSequence = lastSequence;
749
- mediaRow = mediaRows.Get(facade.WixFile.DiskId);
750
- }
751
-
752
- facade.File.Sequence = ++lastSequence;
753
- }
754
- }
755
-
756
- if (null != mediaRow)
757
- {
758
- mediaRow.LastSequence = lastSequence;
759
- }
760
- }
761
- }
762
-
763
- /// <summary>
764
- /// Set the guids for components with generatable guids.
765
- /// </summary>
766
- /// <param name="output">Internal representation of the database to operate on.</param>
767
- private void SetComponentGuids(Output output)
768
- {
769
- Table componentTable = output.Tables["Component"];
770
- if (null != componentTable)
771
- {
772
- Hashtable registryKeyRows = null;
773
- Hashtable directories = null;
774
- Hashtable componentIdGenSeeds = null;
775
- Dictionary<string, List<FileRow>> fileRows = null;
776
-
777
- // find components with generatable guids
778
- foreach (ComponentRow componentRow in componentTable.Rows)
779
- {
780
- // component guid will be generated
781
- if ("*" == componentRow.Guid)
782
- {
783
- if (null == componentRow.KeyPath || componentRow.IsOdbcDataSourceKeyPath)
784
- {
785
- Messaging.Instance.OnMessage(WixErrors.IllegalComponentWithAutoGeneratedGuid(componentRow.SourceLineNumbers));
786
- }
787
- else if (componentRow.IsRegistryKeyPath)
788
- {
789
- if (null == registryKeyRows)
790
- {
791
- Table registryTable = output.Tables["Registry"];
792
-
793
- registryKeyRows = new Hashtable(registryTable.Rows.Count);
794
-
795
- foreach (Row registryRow in registryTable.Rows)
796
- {
797
- registryKeyRows.Add((string)registryRow[0], registryRow);
798
- }
799
- }
800
-
801
- Row foundRow = registryKeyRows[componentRow.KeyPath] as Row;
802
-
803
- string bitness = componentRow.Is64Bit ? "64" : String.Empty;
804
- if (null != foundRow)
805
- {
806
- string regkey = String.Concat(bitness, foundRow[1], "\\", foundRow[2], "\\", foundRow[3]);
807
- componentRow.Guid = Uuid.NewUuid(BindDatabaseCommand.WixComponentGuidNamespace, regkey.ToLowerInvariant()).ToString("B").ToUpperInvariant();
808
- }
809
- }
810
- else // must be a File KeyPath
811
- {
812
- // if the directory table hasn't been loaded into an indexed hash
813
- // of directory ids to target names do that now.
814
- if (null == directories)
815
- {
816
- Table directoryTable = output.Tables["Directory"];
817
-
818
- int numDirectoryTableRows = (null != directoryTable) ? directoryTable.Rows.Count : 0;
819
-
820
- directories = new Hashtable(numDirectoryTableRows);
821
-
822
- // get the target paths for all directories
823
- if (null != directoryTable)
824
- {
825
- foreach (Row row in directoryTable.Rows)
826
- {
827
- // if the directory Id already exists, we will skip it here since
828
- // checking for duplicate primary keys is done later when importing tables
829
- // into database
830
- if (directories.ContainsKey(row[0]))
831
- {
832
- continue;
833
- }
834
-
835
- string targetName = Common.GetName((string)row[2], false, true);
836
- directories.Add(row[0], new ResolvedDirectory((string)row[1], targetName));
837
- }
838
- }
839
- }
840
-
841
- // if the component id generation seeds have not been indexed
842
- // from the WixDirectory table do that now.
843
- if (null == componentIdGenSeeds)
844
- {
845
- Table wixDirectoryTable = output.Tables["WixDirectory"];
846
-
847
- int numWixDirectoryRows = (null != wixDirectoryTable) ? wixDirectoryTable.Rows.Count : 0;
848
-
849
- componentIdGenSeeds = new Hashtable(numWixDirectoryRows);
850
-
851
- // if there are any WixDirectory rows, build up the Component Guid
852
- // generation seeds indexed by Directory/@Id.
853
- if (null != wixDirectoryTable)
854
- {
855
- foreach (Row row in wixDirectoryTable.Rows)
856
- {
857
- componentIdGenSeeds.Add(row[0], (string)row[1]);
858
- }
859
- }
860
- }
861
-
862
- // if the file rows have not been indexed by File.Component yet
863
- // then do that now
864
- if (null == fileRows)
865
- {
866
- Table fileTable = output.Tables["File"];
867
-
868
- int numFileRows = (null != fileTable) ? fileTable.Rows.Count : 0;
869
-
870
- fileRows = new Dictionary<string, List<FileRow>>(numFileRows);
871
-
872
- if (null != fileTable)
873
- {
874
- foreach (FileRow file in fileTable.Rows)
875
- {
876
- List<FileRow> files;
877
- if (!fileRows.TryGetValue(file.Component, out files))
878
- {
879
- files = new List<FileRow>();
880
- fileRows.Add(file.Component, files);
881
- }
882
-
883
- files.Add(file);
884
- }
885
- }
886
- }
887
-
888
- // validate component meets all the conditions to have a generated guid
889
- List<FileRow> currentComponentFiles = fileRows[componentRow.Component];
890
- int numFilesInComponent = currentComponentFiles.Count;
891
- string path = null;
892
-
893
- foreach (FileRow fileRow in currentComponentFiles)
894
- {
895
- if (fileRow.File == componentRow.KeyPath)
896
- {
897
- // calculate the key file's canonical target path
898
- string directoryPath = Binder.GetDirectoryPath(directories, componentIdGenSeeds, componentRow.Directory, true);
899
- string fileName = Common.GetName(fileRow.FileName, false, true).ToLower(CultureInfo.InvariantCulture);
900
- path = Path.Combine(directoryPath, fileName);
901
-
902
- // find paths that are not canonicalized
903
- if (path.StartsWith(@"PersonalFolder\my pictures", StringComparison.Ordinal) ||
904
- path.StartsWith(@"ProgramFilesFolder\common files", StringComparison.Ordinal) ||
905
- path.StartsWith(@"ProgramMenuFolder\startup", StringComparison.Ordinal) ||
906
- path.StartsWith("TARGETDIR", StringComparison.Ordinal) ||
907
- path.StartsWith(@"StartMenuFolder\programs", StringComparison.Ordinal) ||
908
- path.StartsWith(@"WindowsFolder\fonts", StringComparison.Ordinal))
909
- {
910
- Messaging.Instance.OnMessage(WixErrors.IllegalPathForGeneratedComponentGuid(componentRow.SourceLineNumbers, fileRow.Component, path));
911
- }
912
-
913
- // if component has more than one file, the key path must be versioned
914
- if (1 < numFilesInComponent && String.IsNullOrEmpty(fileRow.Version))
915
- {
916
- Messaging.Instance.OnMessage(WixErrors.IllegalGeneratedGuidComponentUnversionedKeypath(componentRow.SourceLineNumbers));
917
- }
918
- }
919
- else
920
- {
921
- // not a key path, so it must be an unversioned file if component has more than one file
922
- if (1 < numFilesInComponent && !String.IsNullOrEmpty(fileRow.Version))
923
- {
924
- Messaging.Instance.OnMessage(WixErrors.IllegalGeneratedGuidComponentVersionedNonkeypath(componentRow.SourceLineNumbers));
925
- }
926
- }
927
- }
928
-
929
- // if the rules were followed, reward with a generated guid
930
- if (!Messaging.Instance.EncounteredError)
931
- {
932
- componentRow.Guid = Uuid.NewUuid(BindDatabaseCommand.WixComponentGuidNamespace, path).ToString("B").ToUpperInvariant();
933
- }
934
- }
935
- }
936
- }
937
- }
938
- }
647
648
+#if TODO_FIX_INSTANCE_TRANSFORM
649
/// <summary>
650
/// Creates instance transform substorages in the output.
651
/// </summary>
@@ -1171,6 +880,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
880
}
881
}
882
}
883
+#endif
884
885
/// <summary>
886
/// Validate that there are no duplicate GUIDs in the output.
@@ -1186,7 +896,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
896
{
897
Dictionary<string, bool> componentGuidConditions = new Dictionary<string, bool>(componentTable.Rows.Count);
898
1189
- foreach (ComponentRow row in componentTable.Rows)
899
+ foreach (Data.Rows.ComponentRow row in componentTable.Rows)
900
{
901
// we don't care about unmanaged components and if there's a * GUID remaining,
902
// there's already an error that prevented it from being replaced with a real GUID.
@@ -1221,7 +931,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
931
/// <param name="output">Internal representation of the msi database to operate upon.</param>
932
private void UpdateControlText(Output output)
933
{
1224
- UpdateControlTextCommand command = new UpdateControlTextCommand();
934
+ var command = new UpdateControlTextCommand();
935
command.BBControlTable = output.Tables["BBControl"];
936
command.WixBBControlTable = output.Tables["WixBBControl"];
937
command.ControlTable = output.Tables["Control"];
@@ -1229,7 +939,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
939
command.Execute();
940
}
941
1232
- private string ResolveMedia(MediaRow mediaRow, string mediaLayoutDirectory, string layoutDirectory)
942
+ private string ResolveMedia(MediaTuple mediaRow, string mediaLayoutDirectory, string layoutDirectory)
943
{
944
string layout = null;
945
@@ -1282,7 +992,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
992
command.TempFilesLocation = this.IntermediateFolder;
993
command.Codepage = this.Codepage;
994
command.Execute();
1285
-#endif
995
}
996
}
997
}
src/WixToolset.Core.WindowsInstaller/Bind/BindSummaryInfoCommand.cs
+92
-86
@@ -1,20 +1,24 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
using System.Globalization;
7
+ using System.Linq;
8
using WixToolset.Data;
9
+ using WixToolset.Data.Tuples;
10
11
/// <summary>
12
/// Binds the summary information table of a database.
13
/// </summary>
14
internal class BindSummaryInfoCommand
15
{
14
- /// <summary>
15
- /// The output to bind.
16
- /// </summary>
17
- public Output Output { private get; set; }
16
+ public BindSummaryInfoCommand(IntermediateSection section)
17
+ {
18
+ this.Section = section;
19
+ }
20
+
21
+ private IntermediateSection Section { get; }
22
23
/// <summary>
24
/// Returns a flag indicating if files are compressed by default.
@@ -40,95 +44,97 @@ namespace WixToolset.Core.WindowsInstaller.Databases
44
this.InstallerVersion = 0;
45
this.ModularizationGuid = null;
46
43
- Table summaryInformationTable = this.Output.Tables["_SummaryInformation"];
47
+ bool foundCreateDataTime = false;
48
+ bool foundLastSaveDataTime = false;
49
+ bool foundCreatingApplication = false;
50
+ string now = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture);
51
45
- if (null != summaryInformationTable)
52
+ foreach (var summaryInformationRow in this.Section.Tuples.OfType<_SummaryInformationTuple>())
53
{
47
- bool foundCreateDataTime = false;
48
- bool foundLastSaveDataTime = false;
49
- bool foundCreatingApplication = false;
50
- string now = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture);
51
-
52
- foreach (Row summaryInformationRow in summaryInformationTable.Rows)
54
+ switch (summaryInformationRow.PropertyId)
55
{
54
- switch (summaryInformationRow.FieldAsInteger(0))
55
- {
56
- case 1: // PID_CODEPAGE
56
+ case 1: // PID_CODEPAGE
57
// make sure the code page is an int and not a web name or null
58
- string codepage = summaryInformationRow.FieldAsString(1);
59
-
60
- if (null == codepage)
61
- {
62
- codepage = "0";
63
- }
64
- else
65
- {
66
- summaryInformationRow[1] = Common.GetValidCodePage(codepage, false, false, summaryInformationRow.SourceLineNumbers).ToString(CultureInfo.InvariantCulture);
67
- }
68
- break;
69
- case 9: // PID_REVNUMBER
70
- string packageCode = (string)summaryInformationRow[1];
71
-
72
- if (OutputType.Module == this.Output.Type)
73
- {
74
- this.ModularizationGuid = packageCode.Substring(1, 36).Replace('-', '_');
75
- }
76
- else if ("*" == packageCode)
77
- {
78
- // set the revision number (package/patch code) if it should be automatically generated
79
- summaryInformationRow[1] = Common.GenerateGuid();
80
- }
81
- break;
82
- case 12: // PID_CREATE_DTM
83
- foundCreateDataTime = true;
84
- break;
85
- case 13: // PID_LASTSAVE_DTM
86
- foundLastSaveDataTime = true;
87
- break;
88
- case 14:
89
- this.InstallerVersion = summaryInformationRow.FieldAsInteger(1);
90
- break;
91
- case 15: // PID_WORDCOUNT
92
- if (OutputType.Patch == this.Output.Type)
93
- {
94
- this.LongNames = true;
95
- this.Compressed = true;
96
- }
97
- else
98
- {
99
- this.LongNames = (0 == (summaryInformationRow.FieldAsInteger(1) & 1));
100
- this.Compressed = (2 == (summaryInformationRow.FieldAsInteger(1) & 2));
101
- }
102
- break;
103
- case 18: // PID_APPNAME
104
- foundCreatingApplication = true;
105
- break;
106
- }
107
- }
58
+ var codepage = summaryInformationRow.Value;
59
109
- // add a summary information row for the create time/date property if its not already set
110
- if (!foundCreateDataTime)
111
- {
112
- Row createTimeDateRow = summaryInformationTable.CreateRow(null);
113
- createTimeDateRow[0] = 12;
114
- createTimeDateRow[1] = now;
115
- }
60
+ if (String.IsNullOrEmpty(codepage))
61
+ {
62
+ codepage = "0";
63
+ }
64
+ else
65
+ {
66
+ summaryInformationRow.Value = Common.GetValidCodePage(codepage, false, false, summaryInformationRow.SourceLineNumbers).ToString(CultureInfo.InvariantCulture);
67
+ }
68
+ break;
69
+ case 9: // PID_REVNUMBER
70
+ var packageCode = summaryInformationRow.Value;
71
117
- // add a summary information row for the last save time/date property if its not already set
118
- if (!foundLastSaveDataTime)
119
- {
120
- Row lastSaveTimeDateRow = summaryInformationTable.CreateRow(null);
121
- lastSaveTimeDateRow[0] = 13;
122
- lastSaveTimeDateRow[1] = now;
72
+ if (SectionType.Module == this.Section.Type)
73
+ {
74
+ this.ModularizationGuid = packageCode.Substring(1, 36).Replace('-', '_');
75
+ }
76
+ else if ("*" == packageCode)
77
+ {
78
+ // set the revision number (package/patch code) if it should be automatically generated
79
+ summaryInformationRow.Value = Common.GenerateGuid();
80
+ }
81
+ break;
82
+ case 12: // PID_CREATE_DTM
83
+ foundCreateDataTime = true;
84
+ break;
85
+ case 13: // PID_LASTSAVE_DTM
86
+ foundLastSaveDataTime = true;
87
+ break;
88
+ case 14:
89
+ this.InstallerVersion = summaryInformationRow[_SummaryInformationTupleFields.Value].AsNumber();
90
+ break;
91
+ case 15: // PID_WORDCOUNT
92
+ if (SectionType.Patch == this.Section.Type)
93
+ {
94
+ this.LongNames = true;
95
+ this.Compressed = true;
96
+ }
97
+ else
98
+ {
99
+ var attributes = summaryInformationRow[_SummaryInformationTupleFields.Value].AsNumber();
100
+ this.LongNames = (0 == (attributes & 1));
101
+ this.Compressed = (2 == (attributes & 2));
102
+ }
103
+ break;
104
+ case 18: // PID_APPNAME
105
+ foundCreatingApplication = true;
106
+ break;
107
}
108
+ }
109
125
- // add a summary information row for the creating application property if its not already set
126
- if (!foundCreatingApplication)
127
- {
128
- Row creatingApplicationRow = summaryInformationTable.CreateRow(null);
129
- creatingApplicationRow[0] = 18;
130
- creatingApplicationRow[1] = String.Format(CultureInfo.InvariantCulture, AppCommon.GetCreatingApplicationString());
131
- }
110
+ // add a summary information row for the create time/date property if its not already set
111
+ if (!foundCreateDataTime)
112
+ {
113
+ var createTimeDateRow = new _SummaryInformationTuple(null, new Identifier(12, AccessModifier.Private));
114
+ createTimeDateRow.PropertyId = 12;
115
+ createTimeDateRow.Value = now;
116
+
117
+ this.Section.Tuples.Add(createTimeDateRow);
118
+ }
119
+
120
+ // add a summary information row for the last save time/date property if its not already set
121
+ if (!foundLastSaveDataTime)
122
+ {
123
+ var lastSaveTimeDateRow = new _SummaryInformationTuple(null, new Identifier(13, AccessModifier.Private));
124
+ lastSaveTimeDateRow.PropertyId = 13;
125
+ lastSaveTimeDateRow.Value = now;
126
+
127
+ this.Section.Tuples.Add(lastSaveTimeDateRow);
128
+ }
129
+
130
+ // add a summary information row for the creating application property if its not already set
131
+ if (!foundCreatingApplication)
132
+ {
133
+ var creatingApplicationRow = new _SummaryInformationTuple(null, new Identifier(18, AccessModifier.Private));
134
+ creatingApplicationRow.PropertyId = 18;
135
+ creatingApplicationRow.Value = String.Format(CultureInfo.InvariantCulture, AppCommon.GetCreatingApplicationString());
136
+
137
+ this.Section.Tuples.Add(creatingApplicationRow);
138
}
139
}
140
}
src/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs
+1
-1
@@ -1,6 +1,6 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
using System.Collections.Generic;
src/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs
+1
-1
@@ -1,6 +1,6 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
using System.Collections;
src/WixToolset.Core.WindowsInstaller/Bind/CabinetWorkItem.cs
+1
-2
@@ -1,11 +1,10 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System.Collections.Generic;
6
using WixToolset.Core.Bind;
7
using WixToolset.Data;
8
- using WixToolset.Data.Rows;
8
9
/// <summary>
10
/// A cabinet builder work item.
src/WixToolset.Core.WindowsInstaller/Bind/CalculateComponentGuids.cs
new
+174
@@ -0,0 +1,174 @@
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.IO;
8
+ using System.Linq;
9
+ using WixToolset.Bind;
10
+ using WixToolset.Core.Native;
11
+ using WixToolset.Data;
12
+ using WixToolset.Data.Tuples;
13
+
14
+ /// <summary>
15
+ /// Set the guids for components with generatable guids.
16
+ /// </summary>
17
+ internal class CalculateComponentGuids
18
+ {
19
+ public CalculateComponentGuids(IntermediateSection section)
20
+ {
21
+ this.Section = section;
22
+ }
23
+
24
+ private IntermediateSection Section { get; }
25
+
26
+ public void Execute()
27
+ {
28
+ Dictionary<string, RegistryTuple> registryKeyRows = null;
29
+ Dictionary<string, ResolvedDirectory> targetPathsByDirectoryId = null;
30
+ Dictionary<string, string> componentIdGenSeeds = null;
31
+ Dictionary<string, List<FileTuple>> filesByComponentId = null;
32
+
33
+ // Find components with generatable guids.
34
+ foreach (var componentRow in this.Section.Tuples.OfType<ComponentTuple>())
35
+ {
36
+ // Skip components that do not specify generate guid.
37
+ if (componentRow.ComponentId != "*")
38
+ {
39
+ continue;
40
+ }
41
+
42
+ var odbcDataSourceKeyPath = (componentRow.Attributes & MsiInterop.MsidbComponentAttributesODBCDataSource) != 0;
43
+
44
+ if (String.IsNullOrEmpty(componentRow.KeyPath) || odbcDataSourceKeyPath)
45
+ {
46
+ Messaging.Instance.OnMessage(WixErrors.IllegalComponentWithAutoGeneratedGuid(componentRow.SourceLineNumbers));
47
+ continue;
48
+ }
49
+
50
+ var registryKeyPath = (componentRow.Attributes & MsiInterop.MsidbComponentAttributesRegistryKeyPath) != 0;
51
+
52
+ if (registryKeyPath)
53
+ {
54
+ if (registryKeyRows is null)
55
+ {
56
+ registryKeyRows = this.Section.Tuples.OfType<RegistryTuple>().ToDictionary(t => t.Registry);
57
+ }
58
+
59
+ if (registryKeyRows.TryGetValue(componentRow.KeyPath, out var foundRow))
60
+ {
61
+ var is64Bit = (componentRow.Attributes & MsiInterop.MsidbComponentAttributes64bit) != 0;
62
+ var bitness = is64Bit ? "64" : String.Empty;
63
+ var regkey = String.Concat(bitness, foundRow[1], "\\", foundRow[2], "\\", foundRow[3]);
64
+ componentRow.ComponentId = Uuid.NewUuid(BindDatabaseCommand.WixComponentGuidNamespace, regkey.ToLowerInvariant()).ToString("B").ToUpperInvariant();
65
+ }
66
+ }
67
+ else // must be a File KeyPath.
68
+ {
69
+ // If the directory table hasn't been loaded into an indexed hash
70
+ // of directory ids to target names do that now.
71
+ if (targetPathsByDirectoryId is null)
72
+ {
73
+ var directories = this.Section.Tuples.OfType<DirectoryTuple>().ToList();
74
+
75
+ targetPathsByDirectoryId = new Dictionary<string, ResolvedDirectory>(directories.Count);
76
+
77
+ // Get the target paths for all directories.
78
+ foreach (var row in directories)
79
+ {
80
+ // If the directory Id already exists, we will skip it here since
81
+ // checking for duplicate primary keys is done later when importing tables
82
+ // into database
83
+ if (targetPathsByDirectoryId.ContainsKey(row.Directory))
84
+ {
85
+ continue;
86
+ }
87
+
88
+ var targetName = Common.GetName(row.DefaultDir, false, true);
89
+ targetPathsByDirectoryId.Add(row.Directory, new ResolvedDirectory(row.Directory_Parent, targetName));
90
+ }
91
+ }
92
+
93
+ // If the component id generation seeds have not been indexed
94
+ // from the WixDirectory table do that now.
95
+ if (componentIdGenSeeds is null)
96
+ {
97
+ // If there are any WixDirectory rows, build up the Component Guid
98
+ // generation seeds indexed by Directory/@Id.
99
+ componentIdGenSeeds = this.Section.Tuples.OfType<WixDirectoryTuple>()
100
+ .Where(t => !String.IsNullOrEmpty(t.ComponentGuidGenerationSeed))
101
+ .ToDictionary(t => t.Directory_, t => t.ComponentGuidGenerationSeed);
102
+ }
103
+
104
+ // if the file rows have not been indexed by File.Component yet
105
+ // then do that now
106
+ if (filesByComponentId is null)
107
+ {
108
+ var files = this.Section.Tuples.OfType<FileTuple>().ToList();
109
+
110
+ filesByComponentId = new Dictionary<string, List<FileTuple>>(files.Count);
111
+
112
+ foreach (var file in files)
113
+ {
114
+ if (!filesByComponentId.TryGetValue(file.Component_, out var componentFiles))
115
+ {
116
+ componentFiles = new List<FileTuple>();
117
+ filesByComponentId.Add(file.Component_, componentFiles);
118
+ }
119
+
120
+ componentFiles.Add(file);
121
+ }
122
+ }
123
+
124
+ // validate component meets all the conditions to have a generated guid
125
+ var currentComponentFiles = filesByComponentId[componentRow.Component];
126
+ var numFilesInComponent = currentComponentFiles.Count;
127
+ string path = null;
128
+
129
+ foreach (var fileRow in currentComponentFiles)
130
+ {
131
+ if (fileRow.File == componentRow.KeyPath)
132
+ {
133
+ // calculate the key file's canonical target path
134
+ string directoryPath = Binder.GetDirectoryPath(targetPathsByDirectoryId, componentIdGenSeeds, componentRow.Directory_, true);
135
+ string fileName = Common.GetName(fileRow.LongFileName, false, true).ToLowerInvariant();
136
+ path = Path.Combine(directoryPath, fileName);
137
+
138
+ // find paths that are not canonicalized
139
+ if (path.StartsWith(@"PersonalFolder\my pictures", StringComparison.Ordinal) ||
140
+ path.StartsWith(@"ProgramFilesFolder\common files", StringComparison.Ordinal) ||
141
+ path.StartsWith(@"ProgramMenuFolder\startup", StringComparison.Ordinal) ||
142
+ path.StartsWith("TARGETDIR", StringComparison.Ordinal) ||
143
+ path.StartsWith(@"StartMenuFolder\programs", StringComparison.Ordinal) ||
144
+ path.StartsWith(@"WindowsFolder\fonts", StringComparison.Ordinal))
145
+ {
146
+ Messaging.Instance.OnMessage(WixErrors.IllegalPathForGeneratedComponentGuid(componentRow.SourceLineNumbers, fileRow.Component_, path));
147
+ }
148
+
149
+ // if component has more than one file, the key path must be versioned
150
+ if (1 < numFilesInComponent && String.IsNullOrEmpty(fileRow.Version))
151
+ {
152
+ Messaging.Instance.OnMessage(WixErrors.IllegalGeneratedGuidComponentUnversionedKeypath(componentRow.SourceLineNumbers));
153
+ }
154
+ }
155
+ else
156
+ {
157
+ // not a key path, so it must be an unversioned file if component has more than one file
158
+ if (1 < numFilesInComponent && !String.IsNullOrEmpty(fileRow.Version))
159
+ {
160
+ Messaging.Instance.OnMessage(WixErrors.IllegalGeneratedGuidComponentVersionedNonkeypath(componentRow.SourceLineNumbers));
161
+ }
162
+ }
163
+ }
164
+
165
+ // if the rules were followed, reward with a generated guid
166
+ if (!Messaging.Instance.EncounteredError)
167
+ {
168
+ componentRow.ComponentId = Uuid.NewUuid(BindDatabaseCommand.WixComponentGuidNamespace, path).ToString("B").ToUpperInvariant();
169
+ }
170
+ }
171
+ }
172
+ }
173
+ }
174
+}
src/WixToolset.Core.WindowsInstaller/Bind/ConfigurationCallback.cs
+1
-1
@@ -1,6 +1,6 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
using System.Collections;
src/WixToolset.Core.WindowsInstaller/Bind/CopyTransformDataCommand.cs
+4
-3
@@ -1,6 +1,6 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
using System.Collections.Generic;
@@ -10,6 +10,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
10
using WixToolset.Extensibility;
11
using WixToolset.Core.Native;
12
using WixToolset.Core.Bind;
13
+ using WixToolset.Data.Tuples;
14
15
internal class CopyTransformDataCommand
16
{
@@ -29,7 +30,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
30
31
List<FileFacade> allFileRows = this.CopyOutFileRows ? new List<FileFacade>() : null;
32
32
-#if false // TODO: Fix this patching related code to work correctly with FileFacades.
33
+#if REVISIT_FOR_PATCHING // TODO: Fix this patching related code to work correctly with FileFacades.
34
bool copyToPatch = (allFileRows != null);
35
bool copyFromPatch = !copyToPatch;
36
@@ -454,7 +455,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
455
}
456
457
Row patchAction = iesTable.CreateRow(null);
457
- WixActionRow wixPatchAction = WindowsInstallerStandard.GetStandardActions()[table, "PatchFiles"];
458
+ WixActionRow wixPatchAction = WindowsInstallerStandardInternal.GetStandardActionRows()[table, "PatchFiles"];
459
int sequence = wixPatchAction.Sequence;
460
// Test for default sequence value's appropriateness
461
if (seqInstallFiles >= sequence || (0 != seqDuplicateFiles && seqDuplicateFiles <= sequence))
src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs
+10
-14
@@ -1,6 +1,6 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
using System.Collections.Generic;
@@ -10,10 +10,10 @@ namespace WixToolset.Core.WindowsInstaller.Databases
10
using System.Runtime.InteropServices;
11
using System.Threading;
12
using WixToolset.Core.Bind;
13
- using WixToolset.Core.WindowsInstaller.Bind;
13
using WixToolset.Data;
14
using WixToolset.Data.Bind;
15
using WixToolset.Data.Rows;
16
+ using WixToolset.Data.Tuples;
17
using WixToolset.Extensibility;
18
19
/// <summary>
@@ -60,9 +60,9 @@ namespace WixToolset.Core.WindowsInstaller.Databases
60
61
public bool Compressed { private get; set; }
62
63
- public Dictionary<MediaRow, IEnumerable<FileFacade>> FileRowsByCabinet { private get; set; }
63
+ public Dictionary<MediaTuple, IEnumerable<FileFacade>> FileRowsByCabinet { private get; set; }
64
65
- public Func<MediaRow, string, string, string> ResolveMedia { private get; set; }
65
+ public Func<MediaTuple, string, string, string> ResolveMedia { private get; set; }
66
67
public TableDefinitionCollection TableDefinitions { private get; set; }
68
@@ -77,7 +77,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
77
/// <returns>The uncompressed file rows.</returns>
78
public void Execute()
79
{
80
- RowDictionary<WixMediaRow> wixMediaRows = new RowDictionary<WixMediaRow>(this.WixMediaTable);
80
+ var wixMediaRows = new RowDictionary<WixMediaRow>(this.WixMediaTable);
81
82
this.lastCabinetAddedToMediaTable = new Dictionary<string, string>();
83
@@ -87,22 +87,19 @@ namespace WixToolset.Core.WindowsInstaller.Databases
87
CabinetBuilder cabinetBuilder = new CabinetBuilder(this.CabbingThreadCount, Marshal.GetFunctionPointerForDelegate(this.newCabNamesCallBack));
88
89
// Supply Compile MediaTemplate Attributes to Cabinet Builder
90
- int MaximumCabinetSizeForLargeFileSplitting;
91
- int MaximumUncompressedMediaSize;
92
- this.GetMediaTemplateAttributes(out MaximumCabinetSizeForLargeFileSplitting, out MaximumUncompressedMediaSize);
90
+ this.GetMediaTemplateAttributes(out var MaximumCabinetSizeForLargeFileSplitting, out var MaximumUncompressedMediaSize);
91
cabinetBuilder.MaximumCabinetSizeForLargeFileSplitting = MaximumCabinetSizeForLargeFileSplitting;
92
cabinetBuilder.MaximumUncompressedMediaSize = MaximumUncompressedMediaSize;
93
94
foreach (var entry in this.FileRowsByCabinet)
95
{
98
- MediaRow mediaRow = entry.Key;
96
+ var mediaRow = entry.Key;
97
IEnumerable<FileFacade> files = entry.Value;
98
CompressionLevel compressionLevel = this.DefaultCompressionLevel;
99
102
- WixMediaRow wixMediaRow = null;
100
string mediaLayoutFolder = null;
101
105
- if (wixMediaRows.TryGetValue(mediaRow.GetKey(), out wixMediaRow))
102
+ if (wixMediaRows.TryGetValue(mediaRow.Id.Id, out var wixMediaRow))
103
{
104
mediaLayoutFolder = wixMediaRow.Layout;
105
@@ -185,7 +182,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
182
/// <param name="fileFacades">Collection of files in this cabinet.</param>
183
/// <param name="fileTransfers">Array of files to be transfered.</param>
184
/// <returns>created CabinetWorkItem object</returns>
188
- private CabinetWorkItem CreateCabinetWorkItem(Output output, string cabinetDir, MediaRow mediaRow, CompressionLevel compressionLevel, IEnumerable<FileFacade> fileFacades, List<FileTransfer> fileTransfers)
185
+ private CabinetWorkItem CreateCabinetWorkItem(Output output, string cabinetDir, MediaTuple mediaRow, CompressionLevel compressionLevel, IEnumerable<FileFacade> fileFacades, List<FileTransfer> fileTransfers)
186
{
187
CabinetWorkItem cabinetWorkItem = null;
188
string tempCabinetFileX = Path.Combine(this.TempFilesLocation, mediaRow.Cabinet);
@@ -254,8 +251,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
251
else
252
{
253
string destinationPath = Path.Combine(cabinetDir, mediaRow.Cabinet);
257
- FileTransfer transfer;
258
- if (FileTransfer.TryCreate(resolvedCabinet.Path, destinationPath, CabinetBuildOption.BuildAndMove == resolvedCabinet.BuildOption, "Cabinet", mediaRow.SourceLineNumbers, out transfer))
254
+ if (FileTransfer.TryCreate(resolvedCabinet.Path, destinationPath, CabinetBuildOption.BuildAndMove == resolvedCabinet.BuildOption, "Cabinet", mediaRow.SourceLineNumbers, out var transfer))
255
{
256
transfer.Built = true;
257
fileTransfers.Add(transfer);
src/WixToolset.Core.WindowsInstaller/Bind/CreateDeltaPatchesCommand.cs
+18
-26
@@ -1,6 +1,6 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
using System.Collections.Generic;
@@ -9,49 +9,40 @@ namespace WixToolset.Core.WindowsInstaller.Databases
9
using WixToolset.Core.Bind;
10
using WixToolset.Data;
11
using WixToolset.Data.Rows;
12
+ using WixToolset.Data.Tuples;
13
14
/// <summary>
15
/// Creates delta patches and updates the appropriate rows to point to the newly generated patches.
16
/// </summary>
17
internal class CreateDeltaPatchesCommand
18
{
18
- public IEnumerable<FileFacade> FileFacades { private get; set; }
19
+ public CreateDeltaPatchesCommand(List<FileFacade> fileFacades, string intermediateFolder, WixPatchIdTuple wixPatchId)
20
+ {
21
+ this.FileFacades = fileFacades;
22
+ this.IntermediateFolder = intermediateFolder;
23
+ this.WixPatchId = wixPatchId;
24
+ }
25
20
- public Table WixPatchIdTable { private get; set; }
26
+ private IEnumerable<FileFacade> FileFacades { get; }
27
22
- public string TempFilesLocation { private get; set; }
28
+ private WixPatchIdTuple WixPatchId { get; }
29
+
30
+ private string IntermediateFolder { get; }
31
32
public void Execute()
33
{
26
-#if REVISIT_FOR_PATCHING
27
- bool optimizePatchSizeForLargeFiles = false;
28
- PatchSymbolFlagsType apiPatchingSymbolFlags = 0;
29
-
30
- if (null != this.WixPatchIdTable)
31
- {
32
- Row row = this.WixPatchIdTable.Rows[0];
33
- if (null != row)
34
- {
35
- if (null != row[2])
36
- {
37
- optimizePatchSizeForLargeFiles = (1 == Convert.ToUInt32(row[2], CultureInfo.InvariantCulture));
38
- }
39
-
40
- if (null != row[3])
41
- {
42
- apiPatchingSymbolFlags = (PatchSymbolFlagsType)Convert.ToUInt32(row[3], CultureInfo.InvariantCulture);
43
- }
44
- }
45
- }
34
+ var optimizePatchSizeForLargeFiles = this.WixPatchId?.OptimizePatchSizeForLargeFiles ?? false;
35
+ var apiPatchingSymbolFlags = (PatchSymbolFlagsType)(this.WixPatchId?.ApiPatchingSymbolFlags ?? 0);
36
37
+#if REVISIT_FOR_PATCHING
38
foreach (FileFacade facade in this.FileFacades)
39
{
40
if (RowOperation.Modify == facade.File.Operation &&
41
0 != (facade.WixFile.PatchAttributes & PatchAttributeType.IncludeWholeFile))
42
{
43
string deltaBase = String.Concat("delta_", facade.File.File);
53
- string deltaFile = Path.Combine(this.TempFilesLocation, String.Concat(deltaBase, ".dpf"));
54
- string headerFile = Path.Combine(this.TempFilesLocation, String.Concat(deltaBase, ".phd"));
44
+ string deltaFile = Path.Combine(this.IntermediateFolder, String.Concat(deltaBase, ".dpf"));
45
+ string headerFile = Path.Combine(this.IntermediateFolder, String.Concat(deltaBase, ".phd"));
46
47
bool retainRangeWarning = false;
48
@@ -84,6 +75,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
75
}
76
}
77
#endif
78
+
79
throw new NotImplementedException();
80
}
81
}
src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs
new
+230
@@ -0,0 +1,230 @@
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.Linq;
7
+ using WixToolset.Core.Native;
8
+ using WixToolset.Data;
9
+ using WixToolset.Data.Rows;
10
+ using WixToolset.Data.Tuples;
11
+
12
+ internal class CreateOutputFromIRCommand
13
+ {
14
+ public CreateOutputFromIRCommand(IntermediateSection section, TableDefinitionCollection tableDefinitions)
15
+ {
16
+ this.Section = section;
17
+ this.TableDefinitions = tableDefinitions;
18
+ }
19
+
20
+ private TableDefinitionCollection TableDefinitions { get; }
21
+
22
+ private IntermediateSection Section { get; }
23
+
24
+ public Output Output { get; private set; }
25
+
26
+ public void Execute()
27
+ {
28
+ var output = new Output(this.Section.Tuples.First().SourceLineNumbers);
29
+ output.Codepage = this.Section.Codepage;
30
+ output.Type = SectionTypeToOutputType(this.Section.Type);
31
+
32
+ this.AddSectionToOutput(this.Section, output);
33
+
34
+ this.Output = output;
35
+ }
36
+
37
+ private void AddSectionToOutput(IntermediateSection section, Output output)
38
+ {
39
+ foreach (var tuple in section.Tuples)
40
+ {
41
+ switch (tuple.Definition.Type)
42
+ {
43
+ case TupleDefinitionType.File:
44
+ this.AddFileTuple((FileTuple)tuple, output);
45
+ break;
46
+
47
+ case TupleDefinitionType.WixAction:
48
+ this.AddWixActionTuple((WixActionTuple)tuple, output);
49
+ break;
50
+
51
+ default:
52
+ this.AddTupleDefaultly(tuple, output);
53
+ break;
54
+ }
55
+ }
56
+ }
57
+
58
+ private void AddFileTuple(FileTuple tuple, Output output)
59
+ {
60
+ var table = output.EnsureTable(this.TableDefinitions["File"]);
61
+ var row = (FileRow)table.CreateRow(tuple.SourceLineNumbers);
62
+ row.File = tuple.File;
63
+ row.Component = tuple.Component_;
64
+ row.FileName = GetMsiFilenameValue(tuple.ShortFileName, tuple.LongFileName);
65
+ row.FileSize = tuple.FileSize;
66
+ row.Version = tuple.Version;
67
+ row.Language = tuple.Language;
68
+
69
+ var attributes = tuple.Checksum ? MsiInterop.MsidbFileAttributesChecksum : 0;
70
+ attributes |= (tuple.Compressed.HasValue && tuple.Compressed.Value) ? MsiInterop.MsidbFileAttributesCompressed : 0;
71
+ attributes |= (tuple.Compressed.HasValue && !tuple.Compressed.Value) ? MsiInterop.MsidbFileAttributesNoncompressed : 0;
72
+ attributes |= tuple.Hidden ? MsiInterop.MsidbFileAttributesHidden : 0;
73
+ attributes |= tuple.ReadOnly ? MsiInterop.MsidbFileAttributesReadOnly : 0;
74
+ attributes |= tuple.System ? MsiInterop.MsidbFileAttributesSystem : 0;
75
+ attributes |= tuple.Vital ? MsiInterop.MsidbFileAttributesVital : 0;
76
+ row.Attributes = attributes;
77
+ }
78
+
79
+ private void AddWixActionTuple(WixActionTuple actionRow, Output output)
80
+ {
81
+ // Get the table definition for the action (and ensure the proper table exists for a module).
82
+ TableDefinition sequenceTableDefinition = null;
83
+ switch (actionRow.SequenceTable)
84
+ {
85
+ case SequenceTable.AdminExecuteSequence:
86
+ if (OutputType.Module == output.Type)
87
+ {
88
+ output.EnsureTable(this.TableDefinitions["AdminExecuteSequence"]);
89
+ sequenceTableDefinition = this.TableDefinitions["ModuleAdminExecuteSequence"];
90
+ }
91
+ else
92
+ {
93
+ sequenceTableDefinition = this.TableDefinitions["AdminExecuteSequence"];
94
+ }
95
+ break;
96
+ case SequenceTable.AdminUISequence:
97
+ if (OutputType.Module == output.Type)
98
+ {
99
+ output.EnsureTable(this.TableDefinitions["AdminUISequence"]);
100
+ sequenceTableDefinition = this.TableDefinitions["ModuleAdminUISequence"];
101
+ }
102
+ else
103
+ {
104
+ sequenceTableDefinition = this.TableDefinitions["AdminUISequence"];
105
+ }
106
+ break;
107
+ case SequenceTable.AdvtExecuteSequence:
108
+ if (OutputType.Module == output.Type)
109
+ {
110
+ output.EnsureTable(this.TableDefinitions["AdvtExecuteSequence"]);
111
+ sequenceTableDefinition = this.TableDefinitions["ModuleAdvtExecuteSequence"];
112
+ }
113
+ else
114
+ {
115
+ sequenceTableDefinition = this.TableDefinitions["AdvtExecuteSequence"];
116
+ }
117
+ break;
118
+ case SequenceTable.InstallExecuteSequence:
119
+ if (OutputType.Module == output.Type)
120
+ {
121
+ output.EnsureTable(this.TableDefinitions["InstallExecuteSequence"]);
122
+ sequenceTableDefinition = this.TableDefinitions["ModuleInstallExecuteSequence"];
123
+ }
124
+ else
125
+ {
126
+ sequenceTableDefinition = this.TableDefinitions["InstallExecuteSequence"];
127
+ }
128
+ break;
129
+ case SequenceTable.InstallUISequence:
130
+ if (OutputType.Module == output.Type)
131
+ {
132
+ output.EnsureTable(this.TableDefinitions["InstallUISequence"]);
133
+ sequenceTableDefinition = this.TableDefinitions["ModuleInstallUISequence"];
134
+ }
135
+ else
136
+ {
137
+ sequenceTableDefinition = this.TableDefinitions["InstallUISequence"];
138
+ }
139
+ break;
140
+ }
141
+
142
+ // create the action sequence row in the output
143
+ var sequenceTable = output.EnsureTable(sequenceTableDefinition);
144
+ var row = sequenceTable.CreateRow(actionRow.SourceLineNumbers);
145
+
146
+ if (SectionType.Module == this.Section.Type)
147
+ {
148
+ row[0] = actionRow.Action;
149
+ if (0 != actionRow.Sequence)
150
+ {
151
+ row[1] = actionRow.Sequence;
152
+ }
153
+ else
154
+ {
155
+ bool after = (null == actionRow.Before);
156
+ row[2] = after ? actionRow.After : actionRow.Before;
157
+ row[3] = after ? 1 : 0;
158
+ }
159
+ row[4] = actionRow.Condition;
160
+ }
161
+ else
162
+ {
163
+ row[0] = actionRow.Action;
164
+ row[1] = actionRow.Condition;
165
+ row[2] = actionRow.Sequence;
166
+ }
167
+ }
168
+
169
+ private void AddTupleDefaultly(IntermediateTuple tuple, Output output)
170
+ {
171
+ if (!this.TableDefinitions.TryGet(tuple.Definition.Name, out var tableDefinition))
172
+ {
173
+ return;
174
+ }
175
+
176
+ var table = output.EnsureTable(tableDefinition);
177
+ var row = table.CreateRow(tuple.SourceLineNumbers);
178
+ for (var i = 0; i < tuple.Fields.Length; ++i)
179
+ {
180
+ if (i < tableDefinition.Columns.Count)
181
+ {
182
+ var column = tableDefinition.Columns[i];
183
+
184
+ switch (column.Type)
185
+ {
186
+ case ColumnType.Number:
187
+ row[i] = tuple.AsNumber(i);
188
+ break;
189
+
190
+ default:
191
+ row[i] = tuple.AsString(i);
192
+ break;
193
+ }
194
+ }
195
+ }
196
+ }
197
+
198
+ private static OutputType SectionTypeToOutputType(SectionType type)
199
+ {
200
+ switch (type)
201
+ {
202
+ case SectionType.Bundle:
203
+ return OutputType.Bundle;
204
+ case SectionType.Module:
205
+ return OutputType.Module;
206
+ case SectionType.Product:
207
+ return OutputType.Product;
208
+ case SectionType.PatchCreation:
209
+ return OutputType.PatchCreation;
210
+ case SectionType.Patch:
211
+ return OutputType.Patch;
212
+
213
+ default:
214
+ throw new ArgumentOutOfRangeException(nameof(type));
215
+ }
216
+ }
217
+
218
+ private static string GetMsiFilenameValue(string shortName, string longName)
219
+ {
220
+ if (String.IsNullOrEmpty(shortName))
221
+ {
222
+ return longName;
223
+ }
224
+ else
225
+ {
226
+ return shortName + "|" + longName;
227
+ }
228
+ }
229
+ }
230
+}
src/WixToolset.Core.WindowsInstaller/Bind/CreateSpecialPropertiesCommand.cs
+46
-41
@@ -1,67 +1,72 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
using System.Collections.Generic;
7
+ using System.Linq;
8
using WixToolset.Data;
8
- using WixToolset.Data.Rows;
9
+ using WixToolset.Data.Tuples;
10
11
internal class CreateSpecialPropertiesCommand
12
{
12
- public Table PropertyTable { private get; set; }
13
+ public CreateSpecialPropertiesCommand(IntermediateSection section)
14
+ {
15
+ this.Section = section;
16
+ }
17
14
- public Table WixPropertyTable { private get; set; }
18
+ private IntermediateSection Section { get; }
19
20
public void Execute()
21
{
18
- // Create the special properties.
19
- if (null != this.WixPropertyTable)
20
- {
21
- // Create lists of the properties that contribute to the special lists of properties.
22
- SortedSet<string> adminProperties = new SortedSet<string>();
23
- SortedSet<string> secureProperties = new SortedSet<string>();
24
- SortedSet<string> hiddenProperties = new SortedSet<string>();
22
+ // Create lists of the properties that contribute to the special lists of properties.
23
+ SortedSet<string> adminProperties = new SortedSet<string>();
24
+ SortedSet<string> secureProperties = new SortedSet<string>();
25
+ SortedSet<string> hiddenProperties = new SortedSet<string>();
26
26
- foreach (WixPropertyRow wixPropertyRow in this.WixPropertyTable.Rows)
27
+ foreach (var wixPropertyRow in this.Section.Tuples.OfType<WixPropertyTuple>())
28
+ {
29
+ if (wixPropertyRow.Admin)
30
{
28
- if (wixPropertyRow.Admin)
29
- {
30
- adminProperties.Add(wixPropertyRow.Id);
31
- }
32
-
33
- if (wixPropertyRow.Hidden)
34
- {
35
- hiddenProperties.Add(wixPropertyRow.Id);
36
- }
37
-
38
- if (wixPropertyRow.Secure)
39
- {
40
- secureProperties.Add(wixPropertyRow.Id);
41
- }
31
+ adminProperties.Add(wixPropertyRow.Property_);
32
}
33
44
- Table propertyTable = this.PropertyTable;
45
- if (0 < adminProperties.Count)
34
+ if (wixPropertyRow.Hidden)
35
{
47
- PropertyRow row = (PropertyRow)propertyTable.CreateRow(null);
48
- row.Property = "AdminProperties";
49
- row.Value = String.Join(";", adminProperties);
36
+ hiddenProperties.Add(wixPropertyRow.Property_);
37
}
38
52
- if (0 < secureProperties.Count)
39
+ if (wixPropertyRow.Secure)
40
{
54
- PropertyRow row = (PropertyRow)propertyTable.CreateRow(null);
55
- row.Property = "SecureCustomProperties";
56
- row.Value = String.Join(";", secureProperties);
41
+ secureProperties.Add(wixPropertyRow.Property_);
42
}
43
+ }
44
59
- if (0 < hiddenProperties.Count)
60
- {
61
- PropertyRow row = (PropertyRow)propertyTable.CreateRow(null);
62
- row.Property = "MsiHiddenProperties";
63
- row.Value = String.Join(";", hiddenProperties);
64
- }
45
+ if (0 < adminProperties.Count)
46
+ {
47
+ var tuple = new PropertyTuple(null, new Identifier("AdminProperties", AccessModifier.Private));
48
+ tuple.Property = "AdminProperties";
49
+ tuple.Value = String.Join(";", adminProperties);
50
+
51
+ this.Section.Tuples.Add(tuple);
52
+ }
53
+
54
+ if (0 < secureProperties.Count)
55
+ {
56
+ var tuple = new PropertyTuple(null, new Identifier("SecureCustomProperties", AccessModifier.Private));
57
+ tuple.Property = "SecureCustomProperties";
58
+ tuple.Value = String.Join(";", secureProperties);
59
+
60
+ this.Section.Tuples.Add(tuple);
61
+ }
62
+
63
+ if (0 < hiddenProperties.Count)
64
+ {
65
+ var tuple = new PropertyTuple(null, new Identifier("MsiHiddenProperties", AccessModifier.Private));
66
+ tuple.Property = "MsiHiddenProperties";
67
+ tuple.Value = String.Join(";", hiddenProperties);
68
+
69
+ this.Section.Tuples.Add(tuple);
70
}
71
}
72
}
src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs
+27
-24
@@ -1,6 +1,6 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
using System.Collections.Generic;
@@ -10,7 +10,6 @@ namespace WixToolset.Core.WindowsInstaller.Databases
10
using System.Linq;
11
using System.Runtime.InteropServices;
12
using WixToolset.Data;
13
- using WixToolset.Data.Rows;
13
using WixToolset.MergeMod;
14
using WixToolset.Msi;
15
using WixToolset.Core.Native;
@@ -23,13 +22,17 @@ namespace WixToolset.Core.WindowsInstaller.Databases
22
/// </summary>
23
internal class ExtractMergeModuleFilesCommand
24
{
26
- public IEnumerable<FileFacade> FileFacades { private get; set; }
25
+ public ExtractMergeModuleFilesCommand(IntermediateSection section, List<WixMergeTuple> wixMergeTuples)
26
+ {
27
+ this.Section = section;
28
+ this.WixMergeTuples = wixMergeTuples;
29
+ }
30
28
- public Table FileTable { private get; set; }
31
+ private IntermediateSection Section { get; }
32
30
- public Table WixFileTable { private get; set; }
33
+ private List<WixMergeTuple> WixMergeTuples { get; }
34
32
- public Table WixMergeTable { private get; set; }
35
+ public IEnumerable<FileFacade> FileFacades { private get; set; }
36
37
public int OutputInstallerVersion { private get; set; }
38
@@ -41,7 +44,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
44
45
public void Execute()
46
{
44
- List<FileFacade> mergeModulesFileFacades = new List<FileFacade>();
47
+ var mergeModulesFileFacades = new List<FileFacade>();
48
49
IMsmMerge2 merge = MsmInterop.GetMsmMerge();
50
@@ -52,9 +55,9 @@ namespace WixToolset.Core.WindowsInstaller.Databases
55
// Now since Merge Modules are already slow and generally less desirable than .wixlibs we'll let
56
// this case be slightly more expensive because the cost of maintaining an indexed file row collection
57
// is a lot more costly for the common cases.
55
- Dictionary<string, FileFacade> indexedFileFacades = this.FileFacades.ToDictionary(f => f.File.File, StringComparer.Ordinal);
58
+ var indexedFileFacades = this.FileFacades.ToDictionary(f => f.File.File, StringComparer.Ordinal);
59
57
- foreach (WixMergeRow wixMergeRow in this.WixMergeTable.Rows)
60
+ foreach (var wixMergeRow in this.WixMergeTuples)
61
{
62
bool containsFiles = this.CreateFacadesForMergeModuleFiles(wixMergeRow, mergeModulesFileFacades, indexedFileFacades);
63
@@ -68,7 +71,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
71
this.MergeModulesFileFacades = mergeModulesFileFacades;
72
}
73
71
- private bool CreateFacadesForMergeModuleFiles(WixMergeRow wixMergeRow, List<FileFacade> mergeModulesFileFacades, Dictionary<string, FileFacade> indexedFileFacades)
74
+ private bool CreateFacadesForMergeModuleFiles(WixMergeTuple wixMergeRow, List<FileFacade> mergeModulesFileFacades, Dictionary<string, FileFacade> indexedFileFacades)
75
{
76
bool containsFiles = false;
77
@@ -98,7 +101,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
101
// rows are created by merging in the actual modules.
102
var fileRow = new FileTuple(wixMergeRow.SourceLineNumbers, new Identifier(record[1], AccessModifier.Private));
103
fileRow.File = record[1];
101
- fileRow.Compressed = (wixMergeRow.FileCompression == YesNoType.Yes) ? true : (wixMergeRow.FileCompression == YesNoType.No) ? (bool?)false : null;
104
+ fileRow.Compressed = wixMergeRow.FileCompression;
105
//FileRow fileRow = (FileRow)this.FileTable.CreateRow(wixMergeRow.SourceLineNumbers, false);
106
//fileRow.File = record[1];
107
//fileRow.Compressed = wixMergeRow.FileCompression;
@@ -107,7 +110,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
110
wixFileRow.Directory_ = record[2];
111
wixFileRow.DiskId = wixMergeRow.DiskId;
112
wixFileRow.PatchGroup = -1;
110
- wixFileRow.Source = Path.Combine(this.IntermediateFolder, "MergeId.", wixMergeRow.Number.ToString(CultureInfo.InvariantCulture), record[1]);
113
+ wixFileRow.Source = Path.Combine(this.IntermediateFolder, wixMergeRow.Id.Id, record[1]);
114
//WixFileRow wixFileRow = (WixFileRow)this.WixFileTable.CreateRow(wixMergeRow.SourceLineNumbers, false);
115
//wixFileRow.Directory = record[2];
116
//wixFileRow.DiskId = wixMergeRow.DiskId;
@@ -119,11 +122,11 @@ namespace WixToolset.Core.WindowsInstaller.Databases
122
// If case-sensitive collision with another merge module or a user-authored file identifier.
123
if (indexedFileFacades.TryGetValue(mergeModuleFileFacade.File.File, out var collidingFacade))
124
{
122
- Messaging.Instance.OnMessage(WixErrors.DuplicateModuleFileIdentifier(wixMergeRow.SourceLineNumbers, wixMergeRow.Id, collidingFacade.File.File));
125
+ Messaging.Instance.OnMessage(WixErrors.DuplicateModuleFileIdentifier(wixMergeRow.SourceLineNumbers, wixMergeRow.Id.Id, collidingFacade.File.File));
126
}
127
else if (uniqueModuleFileIdentifiers.TryGetValue(mergeModuleFileFacade.File.File, out collidingFacade)) // case-insensitive collision with another file identifier in the same merge module
128
{
126
- Messaging.Instance.OnMessage(WixErrors.DuplicateModuleCaseInsensitiveFileIdentifier(wixMergeRow.SourceLineNumbers, wixMergeRow.Id, mergeModuleFileFacade.File.File, collidingFacade.File.File));
129
+ Messaging.Instance.OnMessage(WixErrors.DuplicateModuleCaseInsensitiveFileIdentifier(wixMergeRow.SourceLineNumbers, wixMergeRow.Id.Id, mergeModuleFileFacade.File.File, collidingFacade.File.File));
130
}
131
else // no collision
132
{
@@ -150,12 +153,12 @@ namespace WixToolset.Core.WindowsInstaller.Databases
153
int moduleInstallerVersion = Convert.ToInt32(moduleInstallerVersionString, CultureInfo.InvariantCulture);
154
if (moduleInstallerVersion > this.OutputInstallerVersion)
155
{
153
- Messaging.Instance.OnMessage(WixWarnings.InvalidHigherInstallerVersionInModule(wixMergeRow.SourceLineNumbers, wixMergeRow.Id, moduleInstallerVersion, this.OutputInstallerVersion));
156
+ Messaging.Instance.OnMessage(WixWarnings.InvalidHigherInstallerVersionInModule(wixMergeRow.SourceLineNumbers, wixMergeRow.Id.Id, moduleInstallerVersion, this.OutputInstallerVersion));
157
}
158
}
159
catch (FormatException)
160
{
158
- throw new WixException(WixErrors.MissingOrInvalidModuleInstallerVersion(wixMergeRow.SourceLineNumbers, wixMergeRow.Id, wixMergeRow.SourceFile, moduleInstallerVersionString));
161
+ throw new WixException(WixErrors.MissingOrInvalidModuleInstallerVersion(wixMergeRow.SourceLineNumbers, wixMergeRow.Id.Id, wixMergeRow.SourceFile, moduleInstallerVersionString));
162
}
163
}
164
}
@@ -166,24 +169,26 @@ namespace WixToolset.Core.WindowsInstaller.Databases
169
}
170
catch (Win32Exception)
171
{
169
- throw new WixException(WixErrors.CannotOpenMergeModule(wixMergeRow.SourceLineNumbers, wixMergeRow.Id, wixMergeRow.SourceFile));
172
+ throw new WixException(WixErrors.CannotOpenMergeModule(wixMergeRow.SourceLineNumbers, wixMergeRow.Id.Id, wixMergeRow.SourceFile));
173
}
174
175
return containsFiles;
176
}
177
175
- private void ExtractFilesFromMergeModule(IMsmMerge2 merge, WixMergeRow wixMergeRow)
178
+ private void ExtractFilesFromMergeModule(IMsmMerge2 merge, WixMergeTuple wixMergeRow)
179
{
180
bool moduleOpen = false;
181
short mergeLanguage;
182
183
+ var mergeId = wixMergeRow.Id.Id;
184
+
185
try
186
{
187
mergeLanguage = Convert.ToInt16(wixMergeRow.Language, CultureInfo.InvariantCulture);
188
}
184
- catch (System.FormatException)
189
+ catch (FormatException)
190
{
186
- Messaging.Instance.OnMessage(WixErrors.InvalidMergeLanguage(wixMergeRow.SourceLineNumbers, wixMergeRow.Id, wixMergeRow.Language));
191
+ Messaging.Instance.OnMessage(WixErrors.InvalidMergeLanguage(wixMergeRow.SourceLineNumbers, mergeId, wixMergeRow.Language.ToString()));
192
return;
193
}
194
@@ -192,13 +197,11 @@ namespace WixToolset.Core.WindowsInstaller.Databases
197
merge.OpenModule(wixMergeRow.SourceFile, mergeLanguage);
198
moduleOpen = true;
199
195
- string safeMergeId = wixMergeRow.Number.ToString(CultureInfo.InvariantCulture.NumberFormat);
196
-
200
// extract the module cabinet, then explode all of the files to a temp directory
198
- string moduleCabPath = String.Concat(this.IntermediateFolder, Path.DirectorySeparatorChar, safeMergeId, ".module.cab");
201
+ string moduleCabPath = Path.Combine(this.IntermediateFolder, mergeId + ".cab");
202
merge.ExtractCAB(moduleCabPath);
203
201
- string mergeIdPath = String.Concat(this.IntermediateFolder, Path.DirectorySeparatorChar, "MergeId.", safeMergeId);
204
+ string mergeIdPath = Path.Combine(this.IntermediateFolder, mergeId);
205
Directory.CreateDirectory(mergeIdPath);
206
207
using (var extractCab = new WixExtractCab())
src/WixToolset.Core.WindowsInstaller/Bind/GenerateDatabaseCommand.cs
+1
-1
@@ -1,6 +1,6 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
using System.Collections.Generic;
src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs
+27
-34
@@ -1,6 +1,6 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
using System.Collections.Generic;
@@ -8,57 +8,50 @@ namespace WixToolset.Core.WindowsInstaller.Databases
8
using System.Linq;
9
using WixToolset.Core.Bind;
10
using WixToolset.Data;
11
- using WixToolset.Data.Rows;
11
+ using WixToolset.Data.Tuples;
12
13
internal class GetFileFacadesCommand
14
{
15
- public Table FileTable { private get; set; }
16
-
17
- public Table WixFileTable { private get; set; }
18
-
19
- public Table WixDeltaPatchFileTable { private get; set; }
15
+ public GetFileFacadesCommand(IntermediateSection section)
16
+ {
17
+ this.Section = section;
18
+ }
19
21
- public Table WixDeltaPatchSymbolPathsTable { private get; set; }
20
+ private IntermediateSection Section { get; }
21
22
public List<FileFacade> FileFacades { get; private set; }
23
24
public void Execute()
25
{
27
- throw new NotImplementedException();
28
-#if TODO
29
- List<FileFacade> facades = new List<FileFacade>(this.FileTable.Rows.Count);
26
+ var facades = new List<FileFacade>();
27
31
- RowDictionary<WixFileRow> wixFiles = new RowDictionary<WixFileRow>(this.WixFileTable);
32
- RowDictionary<WixDeltaPatchFileRow> deltaPatchFiles = new RowDictionary<WixDeltaPatchFileRow>(this.WixDeltaPatchFileTable);
28
+ var wixFiles = this.Section.Tuples.OfType<WixFileTuple>().ToDictionary(t => t.File_);
29
+ var deltaPatchFiles = this.Section.Tuples.OfType<WixDeltaPatchFileTuple>().ToDictionary(t => t.File_);
30
34
- foreach (FileRow file in this.FileTable.Rows)
31
+ foreach (var file in this.Section.Tuples.OfType<FileTuple>())
32
{
36
- WixDeltaPatchFileRow deltaPatchFile = null;
33
+ var wixFile = wixFiles[file.File];
34
38
- deltaPatchFiles.TryGetValue(file.File, out deltaPatchFile);
35
+ deltaPatchFiles.TryGetValue(file.File, out var deltaPatchFile);
36
40
- facades.Add(new FileFacade(file, wixFiles[file.File], deltaPatchFile));
37
+ facades.Add(new FileFacade(file, wixFile, deltaPatchFile));
38
}
39
43
- if (null != this.WixDeltaPatchSymbolPathsTable)
44
- {
45
- this.ResolveDeltaPatchSymbolPaths(deltaPatchFiles, facades);
46
- }
40
+ this.ResolveDeltaPatchSymbolPaths(deltaPatchFiles, facades);
41
42
this.FileFacades = facades;
49
-#endif
43
}
44
45
/// <summary>
46
/// Merge data from the WixPatchSymbolPaths rows into the WixDeltaPatchFile rows.
47
/// </summary>
55
- public RowDictionary<WixDeltaPatchFileRow> ResolveDeltaPatchSymbolPaths(RowDictionary<WixDeltaPatchFileRow> deltaPatchFiles, IEnumerable<FileFacade> facades)
48
+ public void ResolveDeltaPatchSymbolPaths(Dictionary<string, WixDeltaPatchFileTuple> deltaPatchFiles, IEnumerable<FileFacade> facades)
49
{
50
ILookup<string, FileFacade> filesByComponent = null;
51
ILookup<string, FileFacade> filesByDirectory = null;
52
ILookup<string, FileFacade> filesByDiskId = null;
53
61
- foreach (WixDeltaPatchSymbolPathsRow row in this.WixDeltaPatchSymbolPathsTable.RowsAs<WixDeltaPatchSymbolPathsRow>().OrderBy(r => r.Type))
54
+ foreach (var row in this.Section.Tuples.OfType<WixDeltaPatchSymbolPathsTuple>().OrderBy(r => r.Type))
55
{
56
switch (row.Type)
57
{
@@ -72,7 +65,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
65
filesByComponent = facades.ToLookup(f => f.File.Component_);
66
}
67
75
- foreach (FileFacade facade in filesByComponent[row.Id])
68
+ foreach (var facade in filesByComponent[row.Id])
69
{
70
this.MergeSymbolPaths(row, deltaPatchFiles[facade.File.File]);
71
}
@@ -84,7 +77,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
77
filesByDirectory = facades.ToLookup(f => f.WixFile.Directory_);
78
}
79
87
- foreach (FileFacade facade in filesByDirectory[row.Id])
80
+ foreach (var facade in filesByDirectory[row.Id])
81
{
82
this.MergeSymbolPaths(row, deltaPatchFiles[facade.File.File]);
83
}
@@ -96,14 +89,14 @@ namespace WixToolset.Core.WindowsInstaller.Databases
89
filesByDiskId = facades.ToLookup(f => f.WixFile.DiskId.ToString(CultureInfo.InvariantCulture));
90
}
91
99
- foreach (FileFacade facade in filesByDiskId[row.Id])
92
+ foreach (var facade in filesByDiskId[row.Id])
93
{
94
this.MergeSymbolPaths(row, deltaPatchFiles[facade.File.File]);
95
}
96
break;
97
98
case SymbolPathType.Product:
106
- foreach (WixDeltaPatchFileRow fileRow in deltaPatchFiles.Values)
99
+ foreach (var fileRow in deltaPatchFiles.Values)
100
{
101
this.MergeSymbolPaths(row, fileRow);
102
}
@@ -114,8 +107,6 @@ namespace WixToolset.Core.WindowsInstaller.Databases
107
break;
108
}
109
}
117
-
118
- return deltaPatchFiles;
110
}
111
112
/// <summary>
@@ -124,17 +115,18 @@ namespace WixToolset.Core.WindowsInstaller.Databases
115
/// <param name="row">Row from the WixPatchSymbolsPaths table.</param>
116
/// <param name="file">FileRow into which to set symbol information.</param>
117
/// <comment>This includes PreviousData as well.</comment>
127
- private void MergeSymbolPaths(WixDeltaPatchSymbolPathsRow row, WixDeltaPatchFileRow file)
118
+ private void MergeSymbolPaths(WixDeltaPatchSymbolPathsTuple row, WixDeltaPatchFileTuple file)
119
{
129
- if (null == file.Symbols)
120
+ if (file.SymbolPaths is null)
121
{
131
- file.Symbols = row.SymbolPaths;
122
+ file.SymbolPaths = row.SymbolPaths;
123
}
124
else
125
{
135
- file.Symbols = String.Concat(file.Symbols, ";", row.SymbolPaths);
126
+ file.SymbolPaths = String.Concat(file.SymbolPaths, ";", row.SymbolPaths);
127
}
128
129
+#if REVISIT_FOR_PATCHING
130
Field field = row.Fields[2];
131
if (null != field.PreviousData)
132
{
@@ -147,6 +139,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
139
file.PreviousSymbols = String.Concat(file.PreviousSymbols, ";", field.PreviousData);
140
}
141
}
142
+#endif
143
}
144
}
145
}
src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs
+10
-22
@@ -1,20 +1,13 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
using System.Collections.Generic;
7
- using System.Collections.Specialized;
8
- using System.ComponentModel;
9
- using System.Diagnostics;
7
using System.Globalization;
8
using System.IO;
12
- using System.Linq;
9
using System.Runtime.InteropServices;
10
using System.Text;
15
- using System.Xml;
16
- using System.Xml.XPath;
17
- using WixToolset.Clr.Interop;
11
using WixToolset.Data;
12
using WixToolset.Data.Rows;
13
using WixToolset.MergeMod;
@@ -35,12 +28,10 @@ namespace WixToolset.Core.WindowsInstaller.Databases
28
29
public IEnumerable<string> SuppressedTableNames { private get; set; }
30
38
- public string TempFilesLocation { private get; set; }
31
+ public string IntermediateFolder { private get; set; }
32
33
public void Execute()
34
{
42
- Debug.Assert(OutputType.Product == this.Output.Type);
43
-
35
Table wixMergeTable = this.Output.Tables["WixMerge"];
36
Table wixFeatureModulesTable = this.Output.Tables["WixFeatureModules"];
37
@@ -59,7 +50,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
50
{
51
merge = MsmInterop.GetMsmMerge();
52
62
- logPath = Path.Combine(this.TempFilesLocation, "merge.log");
53
+ logPath = Path.Combine(this.IntermediateFolder, "merge.log");
54
merge.OpenLog(logPath);
55
logOpen = true;
56
@@ -79,7 +70,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
70
{
71
mergeLanguage = Convert.ToInt16(wixMergeRow.Language, CultureInfo.InvariantCulture);
72
}
82
- catch (System.FormatException)
73
+ catch (FormatException)
74
{
75
Messaging.Instance.OnMessage(WixErrors.InvalidMergeLanguage(wixMergeRow.SourceLineNumbers, wixMergeRow.Id, wixMergeRow.Language));
76
continue;
@@ -284,7 +275,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
275
Messaging.Instance.OnMessage(WixVerboses.ResequencingMergeModuleFiles());
276
using (View view = db.OpenView("SELECT `Sequence`, `Attributes` FROM `File` WHERE `File`=?"))
277
{
287
- foreach (FileFacade file in this.FileFacades)
278
+ foreach (var file in this.FileFacades)
279
{
280
if (!file.FromModule)
281
{
@@ -307,32 +298,29 @@ namespace WixToolset.Core.WindowsInstaller.Databases
298
//recordUpdate.SetInteger(1, file.File.Sequence);
299
throw new NotImplementedException();
300
310
- // update the file attributes to match the compression specified
311
- // on the Merge element or on the Package element
312
- int attributes = 0;
301
+ // Update the file attributes to match the compression specified
302
+ // on the Merge element or on the Package element.
303
+ var attributes = 0;
304
314
- // get the current value if its not null
305
+ // Get the current value if its not null.
306
if (!recordUpdate.IsNull(2))
307
{
308
attributes = recordUpdate.GetInteger(2);
309
}
310
320
- // not specified
311
if (!file.File.Compressed.HasValue)
312
{
323
- // clear any compression bits
313
+ // Clear all compression bits.
314
attributes &= ~MsiInterop.MsidbFileAttributesCompressed;
315
attributes &= ~MsiInterop.MsidbFileAttributesNoncompressed;
316
}
317
else if (file.File.Compressed.Value)
318
{
329
- // these are mutually exclusive
319
attributes |= MsiInterop.MsidbFileAttributesCompressed;
320
attributes &= ~MsiInterop.MsidbFileAttributesNoncompressed;
321
}
322
else if (!file.File.Compressed.Value)
323
{
335
- // these are mutually exclusive
324
attributes |= MsiInterop.MsidbFileAttributesNoncompressed;
325
attributes &= ~MsiInterop.MsidbFileAttributesCompressed;
326
}
src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs
+19
-17
@@ -1,39 +1,42 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
- using System.Collections;
6
using System.Collections.Generic;
7
using System.IO;
8
using WixToolset.Data;
10
- using WixToolset.Data.Rows;
9
using WixToolset.Msi;
10
using WixToolset.Core.Native;
11
using WixToolset.Bind;
12
using WixToolset.Core.Bind;
13
using WixToolset.Data.Bind;
14
+ using WixToolset.Data.Tuples;
15
+ using System.Linq;
16
17
/// <summary>
18
/// Defines the file transfers necessary to layout the uncompressed files.
19
/// </summary>
20
internal class ProcessUncompressedFilesCommand
21
{
22
+ public ProcessUncompressedFilesCommand(IntermediateSection section)
23
+ {
24
+ this.Section = section;
25
+ }
26
+
27
+ private IntermediateSection Section { get; }
28
+
29
public string DatabasePath { private get; set; }
30
31
public IEnumerable<FileFacade> FileFacades { private get; set; }
32
26
- public RowDictionary<MediaRow> MediaRows { private get; set; }
27
-
33
public string LayoutDirectory { private get; set; }
34
35
public bool Compressed { private get; set; }
36
37
public bool LongNamesInImage { private get; set; }
38
34
- public Func<MediaRow, string, string, string> ResolveMedia { private get; set; }
35
-
36
- public Table WixMediaTable { private get; set; }
39
+ public Func<MediaTuple, string, string, string> ResolveMedia { private get; set; }
40
41
public IEnumerable<FileTransfer> FileTransfers { get; private set; }
42
@@ -41,9 +44,11 @@ namespace WixToolset.Core.WindowsInstaller.Databases
44
{
45
List<FileTransfer> fileTransfers = new List<FileTransfer>();
46
44
- Hashtable directories = new Hashtable();
47
+ var directories = new Dictionary<string, ResolvedDirectory>();
48
46
- RowDictionary<WixMediaRow> wixMediaRows = new RowDictionary<WixMediaRow>(this.WixMediaTable);
49
+ var mediaRows = this.Section.Tuples.OfType<MediaTuple>().ToDictionary(t => t.DiskId);
50
+
51
+ var wixMediaRows = this.Section.Tuples.OfType<WixMediaTuple>().ToDictionary(t => t.DiskId_);
52
53
using (Database db = new Database(this.DatabasePath, OpenDatabase.ReadOnly))
54
{
@@ -72,18 +77,16 @@ namespace WixToolset.Core.WindowsInstaller.Databases
77
// for each file in the array of uncompressed files
78
foreach (FileFacade facade in this.FileFacades)
79
{
75
- MediaRow mediaRow = this.MediaRows.Get(facade.WixFile.DiskId);
80
+ var mediaTuple = mediaRows[facade.WixFile.DiskId];
81
string relativeFileLayoutPath = null;
77
-
78
- WixMediaRow wixMediaRow = null;
82
string mediaLayoutFolder = null;
83
81
- if (wixMediaRows.TryGetValue(mediaRow.GetKey(), out wixMediaRow))
84
+ if (wixMediaRows.TryGetValue(facade.WixFile.DiskId, out var wixMediaRow))
85
{
86
mediaLayoutFolder = wixMediaRow.Layout;
87
}
88
86
- string mediaLayoutDirectory = this.ResolveMedia(mediaRow, mediaLayoutFolder, this.LayoutDirectory);
89
+ var mediaLayoutDirectory = this.ResolveMedia(mediaTuple, mediaLayoutFolder, this.LayoutDirectory);
90
91
// setup up the query record and find the appropriate file in the
92
// previously executed file view
@@ -102,8 +105,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
105
106
// finally put together the base media layout path and the relative file layout path
107
string fileLayoutPath = Path.Combine(mediaLayoutDirectory, relativeFileLayoutPath);
105
- FileTransfer transfer;
106
- if (FileTransfer.TryCreate(facade.WixFile.Source, fileLayoutPath, false, "File", facade.File.SourceLineNumbers, out transfer))
108
+ if (FileTransfer.TryCreate(facade.WixFile.Source, fileLayoutPath, false, "File", facade.File.SourceLineNumbers, out var transfer))
109
{
110
fileTransfers.Add(transfer);
111
}
src/WixToolset.Core.WindowsInstaller/Bind/SequenceActionsCommand.cs
new
+671
@@ -0,0 +1,671 @@
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.Core.Native;
10
+ using WixToolset.Data;
11
+ using WixToolset.Data.Tuples;
12
+
13
+ internal class SequenceActionsCommand
14
+ {
15
+ public SequenceActionsCommand(IntermediateSection section)
16
+ {
17
+ this.Section = section;
18
+
19
+ this.RelativeActionsForActions = new Dictionary<string, RelativeActions>();
20
+
21
+ this.StandardActionsById = WindowsInstallerStandard.StandardActions().ToDictionary(a => a.Id.Id);
22
+ }
23
+
24
+ private IntermediateSection Section { get; }
25
+
26
+ private Dictionary<string, RelativeActions> RelativeActionsForActions { get; }
27
+
28
+ private Dictionary<string, WixActionTuple> StandardActionsById { get; }
29
+
30
+ public Messaging Messaging { private get; set; }
31
+
32
+ public void Execute()
33
+ {
34
+ var actions = this.Section.Tuples.OfType<WixActionTuple>().ToList();
35
+ var suppressActions = this.Section.Tuples.OfType<WixSuppressActionTuple>().ToList();
36
+
37
+ this.SequenceActions(actions, suppressActions);
38
+ }
39
+
40
+ /// <summary>
41
+ /// Set sequence numbers for all the actions and create rows in the output object.
42
+ /// </summary>
43
+ /// <param name="actionRows">Collection of actions to schedule.</param>
44
+ /// <param name="suppressActionRows">Collection of actions to suppress.</param>
45
+ private void SequenceActions(List<WixActionTuple> actionRows, List<WixSuppressActionTuple> suppressActionRows)
46
+ {
47
+ var overridableActionRows = new Dictionary<string, WixActionTuple>();
48
+ var requiredActionRows = new Dictionary<string, WixActionTuple>();
49
+
50
+ // Get the standard actions required based on tuples in the section.
51
+ var requiredActionIds = this.GetRequiredActionIds();
52
+
53
+ foreach (var actionId in requiredActionIds)
54
+ {
55
+ var standardAction = this.StandardActionsById[actionId];
56
+
57
+ overridableActionRows.Add(standardAction.Id.Id, standardAction);
58
+ }
59
+
60
+ // Index all the action rows and look for collisions.
61
+ foreach (var actionRow in this.Section.Tuples.OfType<WixActionTuple>())
62
+ {
63
+ if (actionRow.Overridable) // overridable action
64
+ {
65
+ if (overridableActionRows.TryGetValue(actionRow.Id.Id, out var collidingActionRow))
66
+ {
67
+ this.Messaging.OnMessage(WixErrors.OverridableActionCollision(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
68
+ if (null != collidingActionRow.SourceLineNumbers)
69
+ {
70
+ this.Messaging.OnMessage(WixErrors.OverridableActionCollision2(collidingActionRow.SourceLineNumbers));
71
+ }
72
+ }
73
+ else
74
+ {
75
+ overridableActionRows.Add(actionRow.Id.Id, actionRow);
76
+ }
77
+ }
78
+ else // unsequenced or sequenced action.
79
+ {
80
+ // Unsequenced action (allowed for certain standard actions).
81
+ if (null == actionRow.Before && null == actionRow.After && 0 == actionRow.Sequence)
82
+ {
83
+ if (this.StandardActionsById.TryGetValue(actionRow.Id.Id, out var standardAction))
84
+ {
85
+ // Populate the sequence from the standard action
86
+ actionRow.Sequence = standardAction.Sequence;
87
+ }
88
+ else // not a supported unscheduled action.
89
+ {
90
+ throw new InvalidOperationException(WixStrings.EXP_FoundActionRowWithNoSequenceBeforeOrAfterColumnSet);
91
+ }
92
+ }
93
+
94
+ if (overridableActionRows.TryGetValue(actionRow.Id.Id, out var collidingActionRow))
95
+ {
96
+ this.Messaging.OnMessage(WixErrors.ActionCollision(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
97
+ if (null != collidingActionRow.SourceLineNumbers)
98
+ {
99
+ this.Messaging.OnMessage(WixErrors.ActionCollision2(collidingActionRow.SourceLineNumbers));
100
+ }
101
+ }
102
+ else
103
+ {
104
+ requiredActionRows.Add(actionRow.Id.Id, actionRow);
105
+ }
106
+ }
107
+ }
108
+
109
+ // Add the overridable action rows that are not overridden to the required action rows.
110
+ foreach (var actionRow in overridableActionRows.Values)
111
+ {
112
+ if (!requiredActionRows.ContainsKey(actionRow.Id.Id))
113
+ {
114
+ requiredActionRows.Add(actionRow.Id.Id, actionRow);
115
+ }
116
+ }
117
+
118
+ // Suppress the required actions that are overridable.
119
+ foreach (var suppressActionRow in suppressActionRows)
120
+ {
121
+ var key = suppressActionRow.Id.Id;
122
+
123
+ // If there is an overridable row to suppress; suppress it. There is no warning if there
124
+ // is no action to suppress because the action may be suppressed from a merge module in
125
+ // the binder.
126
+ if (requiredActionRows.TryGetValue(key, out var requiredActionRow))
127
+ {
128
+ if (requiredActionRow.Overridable)
129
+ {
130
+ this.Messaging.OnMessage(WixWarnings.SuppressAction(suppressActionRow.SourceLineNumbers, suppressActionRow.Action, suppressActionRow.SequenceTable.ToString()));
131
+ if (null != requiredActionRow.SourceLineNumbers)
132
+ {
133
+ this.Messaging.OnMessage(WixWarnings.SuppressAction2(requiredActionRow.SourceLineNumbers));
134
+ }
135
+
136
+ requiredActionRows.Remove(key);
137
+ }
138
+ else // suppressing a non-overridable action row
139
+ {
140
+ this.Messaging.OnMessage(WixErrors.SuppressNonoverridableAction(suppressActionRow.SourceLineNumbers, suppressActionRow.SequenceTable.ToString(), suppressActionRow.Action));
141
+ if (null != requiredActionRow.SourceLineNumbers)
142
+ {
143
+ this.Messaging.OnMessage(WixErrors.SuppressNonoverridableAction2(requiredActionRow.SourceLineNumbers));
144
+ }
145
+ }
146
+ }
147
+ }
148
+
149
+ // Build up dependency trees of the relatively scheduled actions.
150
+ // Use ToList() to create a copy of the required action rows so that new tuples can
151
+ // be added while enumerating.
152
+ foreach (var actionRow in requiredActionRows.Values.ToList())
153
+ {
154
+ if (0 == actionRow.Sequence)
155
+ {
156
+ // check for standard actions that don't have a sequence number in a merge module
157
+ if (SectionType.Module == this.Section.Type && WindowsInstallerStandard.IsStandardAction(actionRow.Action))
158
+ {
159
+ this.Messaging.OnMessage(WixErrors.StandardActionRelativelyScheduledInModule(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
160
+ }
161
+
162
+ this.SequenceActionRow(actionRow, requiredActionRows);
163
+ }
164
+ else if (SectionType.Module == this.Section.Type && 0 < actionRow.Sequence && !WindowsInstallerStandard.IsStandardAction(actionRow.Action)) // check for custom actions and dialogs that have a sequence number
165
+ {
166
+ this.Messaging.OnMessage(WixErrors.CustomActionSequencedInModule(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
167
+ }
168
+ }
169
+
170
+ // Look for standard actions with sequence restrictions that aren't necessarily scheduled based
171
+ // on the presence of a particular table.
172
+ if (requiredActionRows.ContainsKey("InstallExecuteSequence/DuplicateFiles") && !requiredActionRows.ContainsKey("InstallExecuteSequence/InstallFiles"))
173
+ {
174
+ var standardAction = this.StandardActionsById["InstallExecuteSequence/InstallFiles"];
175
+ requiredActionRows.Add(standardAction.Id.Id, standardAction);
176
+ }
177
+
178
+ // Schedule actions.
179
+ List<WixActionTuple> scheduledActionRows;
180
+ if (SectionType.Module == this.Section.Type)
181
+ {
182
+ scheduledActionRows = requiredActionRows.Values.ToList();
183
+ }
184
+ else
185
+ {
186
+ scheduledActionRows = ScheduleActions(requiredActionRows);
187
+ }
188
+
189
+ // Remove all existing WixActionTuples from the section then add the
190
+ // scheduled actions back to the section. Note: we add the indices in
191
+ // reverse order to make it easy to remove them from the list later.
192
+ var removeIndices = new List<int>();
193
+ for (var i = this.Section.Tuples.Count - 1; i >= 0; --i)
194
+ {
195
+ var tuple = this.Section.Tuples[i];
196
+ if (tuple.Definition.Type == TupleDefinitionType.WixAction)
197
+ {
198
+ removeIndices.Add(i);
199
+ }
200
+ }
201
+
202
+ foreach (var removeIndex in removeIndices)
203
+ {
204
+ this.Section.Tuples.RemoveAt(removeIndex);
205
+ }
206
+
207
+ foreach (var action in scheduledActionRows)
208
+ {
209
+ this.Section.Tuples.Add(action);
210
+ }
211
+ }
212
+
213
+ private List<WixActionTuple> ScheduleActions(Dictionary<string, WixActionTuple> requiredActionRows)
214
+ {
215
+ var scheduledActionRows = new List<WixActionTuple>();
216
+
217
+ // Process each sequence table individually.
218
+ foreach (SequenceTable sequenceTable in Enum.GetValues(typeof(SequenceTable)))
219
+ {
220
+ // Create a collection of just the action rows in this sequence
221
+ var sequenceActionRows = requiredActionRows.Values.Where(a => a.SequenceTable == sequenceTable).ToList();
222
+
223
+ // Schedule the absolutely scheduled actions (by sorting them by their sequence numbers).
224
+ var absoluteActionRows = new List<WixActionTuple>();
225
+ foreach (var actionRow in sequenceActionRows)
226
+ {
227
+ if (0 != actionRow.Sequence)
228
+ {
229
+ // Look for sequence number collisions
230
+ foreach (var sequenceScheduledActionRow in absoluteActionRows)
231
+ {
232
+ if (sequenceScheduledActionRow.Sequence == actionRow.Sequence)
233
+ {
234
+ this.Messaging.OnMessage(WixWarnings.ActionSequenceCollision(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, sequenceScheduledActionRow.Action, actionRow.Sequence));
235
+ if (null != sequenceScheduledActionRow.SourceLineNumbers)
236
+ {
237
+ this.Messaging.OnMessage(WixWarnings.ActionSequenceCollision2(sequenceScheduledActionRow.SourceLineNumbers));
238
+ }
239
+ }
240
+ }
241
+
242
+ absoluteActionRows.Add(actionRow);
243
+ }
244
+ }
245
+
246
+ absoluteActionRows.Sort((x, y) => x.Sequence.CompareTo(y.Sequence));
247
+
248
+ // Schedule the relatively scheduled actions (by resolving the dependency trees).
249
+ var previousUsedSequence = 0;
250
+ var relativeActionRows = new List<WixActionTuple>();
251
+ for (int j = 0; j < absoluteActionRows.Count; j++)
252
+ {
253
+ var absoluteActionRow = absoluteActionRows[j];
254
+
255
+ // Get all the relatively scheduled action rows occuring before and after this absolutely scheduled action row.
256
+ var relativeActions = this.GetAllRelativeActionsForSequenceType(sequenceTable, absoluteActionRow);
257
+
258
+ // Check for relatively scheduled actions occuring before/after a special action
259
+ // (those actions with a negative sequence number).
260
+ if (absoluteActionRow.Sequence < 0 && (relativeActions.PreviousActions.Any() || relativeActions.NextActions.Any()))
261
+ {
262
+ // Create errors for all the before actions.
263
+ foreach (var actionRow in relativeActions.PreviousActions)
264
+ {
265
+ this.Messaging.OnMessage(WixErrors.ActionScheduledRelativeToTerminationAction(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, absoluteActionRow.Action));
266
+ }
267
+
268
+ // Create errors for all the after actions.
269
+ foreach (var actionRow in relativeActions.NextActions)
270
+ {
271
+ this.Messaging.OnMessage(WixErrors.ActionScheduledRelativeToTerminationAction(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, absoluteActionRow.Action));
272
+ }
273
+
274
+ // If there is source line information for the absolutely scheduled action display it
275
+ if (absoluteActionRow.SourceLineNumbers != null)
276
+ {
277
+ this.Messaging.OnMessage(WixErrors.ActionScheduledRelativeToTerminationAction2(absoluteActionRow.SourceLineNumbers));
278
+ }
279
+
280
+ continue;
281
+ }
282
+
283
+ // Schedule the action rows before this one.
284
+ var unusedSequence = absoluteActionRow.Sequence - 1;
285
+ for (var i = relativeActions.PreviousActions.Count - 1; i >= 0; i--)
286
+ {
287
+ var relativeActionRow = relativeActions.PreviousActions[i];
288
+
289
+ // look for collisions
290
+ if (unusedSequence == previousUsedSequence)
291
+ {
292
+ this.Messaging.OnMessage(WixErrors.NoUniqueActionSequenceNumber(relativeActionRow.SourceLineNumbers, relativeActionRow.SequenceTable.ToString(), relativeActionRow.Action, absoluteActionRow.Action));
293
+ if (absoluteActionRow.SourceLineNumbers != null)
294
+ {
295
+ this.Messaging.OnMessage(WixErrors.NoUniqueActionSequenceNumber2(absoluteActionRow.SourceLineNumbers));
296
+ }
297
+
298
+ unusedSequence++;
299
+ }
300
+
301
+ relativeActionRow.Sequence = unusedSequence;
302
+ relativeActionRows.Add(relativeActionRow);
303
+
304
+ unusedSequence--;
305
+ }
306
+
307
+ // Determine the next used action sequence number.
308
+ var nextUsedSequence = Int16.MaxValue + 1;
309
+ if (absoluteActionRows.Count > j + 1)
310
+ {
311
+ nextUsedSequence = absoluteActionRows[j + 1].Sequence;
312
+ }
313
+
314
+ // Schedule the action rows after this one.
315
+ unusedSequence = absoluteActionRow.Sequence + 1;
316
+ for (var i = 0; i < relativeActions.NextActions.Count; i++)
317
+ {
318
+ var relativeActionRow = relativeActions.NextActions[i];
319
+
320
+ if (unusedSequence == nextUsedSequence)
321
+ {
322
+ this.Messaging.OnMessage(WixErrors.NoUniqueActionSequenceNumber(relativeActionRow.SourceLineNumbers, relativeActionRow.SequenceTable.ToString(), relativeActionRow.Action, absoluteActionRow.Action));
323
+ if (absoluteActionRow.SourceLineNumbers != null)
324
+ {
325
+ this.Messaging.OnMessage(WixErrors.NoUniqueActionSequenceNumber2(absoluteActionRow.SourceLineNumbers));
326
+ }
327
+
328
+ unusedSequence--;
329
+ }
330
+
331
+ relativeActionRow.Sequence = unusedSequence;
332
+ relativeActionRows.Add(relativeActionRow);
333
+
334
+ unusedSequence++;
335
+ }
336
+
337
+ // keep track of this sequence number as the previous used sequence number for the next iteration
338
+ previousUsedSequence = absoluteActionRow.Sequence;
339
+ }
340
+
341
+ // add the absolutely and relatively scheduled actions to the list of scheduled actions
342
+ scheduledActionRows.AddRange(absoluteActionRows);
343
+ scheduledActionRows.AddRange(relativeActionRows);
344
+ }
345
+
346
+ return scheduledActionRows;
347
+ }
348
+
349
+ private IEnumerable<string> GetRequiredActionIds()
350
+ {
351
+ var set = new HashSet<string>();
352
+
353
+ // gather the required actions for the output type
354
+ if (SectionType.Product == this.Section.Type)
355
+ {
356
+ // AdminExecuteSequence table
357
+ set.Add("AdminExecuteSequence/CostFinalize");
358
+ set.Add("AdminExecuteSequence/CostInitialize");
359
+ set.Add("AdminExecuteSequence/FileCost");
360
+ set.Add("AdminExecuteSequence/InstallAdminPackage");
361
+ set.Add("AdminExecuteSequence/InstallFiles");
362
+ set.Add("AdminExecuteSequence/InstallFinalize");
363
+ set.Add("AdminExecuteSequence/InstallInitialize");
364
+ set.Add("AdminExecuteSequence/InstallValidate");
365
+
366
+ // AdminUISequence table
367
+ set.Add("AdminUISequence/CostFinalize");
368
+ set.Add("AdminUISequence/CostInitialize");
369
+ set.Add("AdminUISequence/ExecuteAction");
370
+ set.Add("AdminUISequence/FileCost");
371
+
372
+ // AdvtExecuteSequence table
373
+ set.Add("AdvtExecuteSequence/CostFinalize");
374
+ set.Add("AdvtExecuteSequence/CostInitialize");
375
+ set.Add("AdvtExecuteSequence/InstallFinalize");
376
+ set.Add("AdvtExecuteSequence/InstallValidate");
377
+ set.Add("AdvtExecuteSequence/PublishFeatures");
378
+ set.Add("AdvtExecuteSequence/PublishProduct");
379
+
380
+ // InstallExecuteSequence table
381
+ set.Add("InstallExecuteSequence/CostFinalize");
382
+ set.Add("InstallExecuteSequence/CostInitialize");
383
+ set.Add("InstallExecuteSequence/FileCost");
384
+ set.Add("InstallExecuteSequence/InstallFinalize");
385
+ set.Add("InstallExecuteSequence/InstallInitialize");
386
+ set.Add("InstallExecuteSequence/InstallValidate");
387
+ set.Add("InstallExecuteSequence/ProcessComponents");
388
+ set.Add("InstallExecuteSequence/PublishFeatures");
389
+ set.Add("InstallExecuteSequence/PublishProduct");
390
+ set.Add("InstallExecuteSequence/RegisterProduct");
391
+ set.Add("InstallExecuteSequence/RegisterUser");
392
+ set.Add("InstallExecuteSequence/UnpublishFeatures");
393
+ set.Add("InstallExecuteSequence/ValidateProductID");
394
+
395
+ // InstallUISequence table
396
+ set.Add("InstallUISequence/CostFinalize");
397
+ set.Add("InstallUISequence/CostInitialize");
398
+ set.Add("InstallUISequence/ExecuteAction");
399
+ set.Add("InstallUISequence/FileCost");
400
+ set.Add("InstallUISequence/ValidateProductID");
401
+ }
402
+
403
+ // Gather the required actions for each tuple type.
404
+ foreach (var tupleType in this.Section.Tuples.Select(t => t.Definition.Type).Distinct())
405
+ {
406
+ switch (tupleType)
407
+ {
408
+ case TupleDefinitionType.AppSearch:
409
+ set.Add("InstallExecuteSequence/AppSearch");
410
+ set.Add("InstallUISequence/AppSearch");
411
+ break;
412
+ case TupleDefinitionType.BindImage:
413
+ set.Add("InstallExecuteSequence/BindImage");
414
+ break;
415
+ case TupleDefinitionType.CCPSearch:
416
+ set.Add("InstallExecuteSequence/AppSearch");
417
+ set.Add("InstallExecuteSequence/CCPSearch");
418
+ set.Add("InstallExecuteSequence/RMCCPSearch");
419
+ set.Add("InstallUISequence/AppSearch");
420
+ set.Add("InstallUISequence/CCPSearch");
421
+ set.Add("InstallUISequence/RMCCPSearch");
422
+ break;
423
+ case TupleDefinitionType.Class:
424
+ set.Add("AdvtExecuteSequence/RegisterClassInfo");
425
+ set.Add("InstallExecuteSequence/RegisterClassInfo");
426
+ set.Add("InstallExecuteSequence/UnregisterClassInfo");
427
+ break;
428
+ case TupleDefinitionType.Complus:
429
+ set.Add("InstallExecuteSequence/RegisterComPlus");
430
+ set.Add("InstallExecuteSequence/UnregisterComPlus");
431
+ break;
432
+ case TupleDefinitionType.CreateFolder:
433
+ set.Add("InstallExecuteSequence/CreateFolders");
434
+ set.Add("InstallExecuteSequence/RemoveFolders");
435
+ break;
436
+ case TupleDefinitionType.DuplicateFile:
437
+ set.Add("InstallExecuteSequence/DuplicateFiles");
438
+ set.Add("InstallExecuteSequence/RemoveDuplicateFiles");
439
+ break;
440
+ case TupleDefinitionType.Environment:
441
+ set.Add("InstallExecuteSequence/WriteEnvironmentStrings");
442
+ set.Add("InstallExecuteSequence/RemoveEnvironmentStrings");
443
+ break;
444
+ case TupleDefinitionType.Extension:
445
+ set.Add("AdvtExecuteSequence/RegisterExtensionInfo");
446
+ set.Add("InstallExecuteSequence/RegisterExtensionInfo");
447
+ set.Add("InstallExecuteSequence/UnregisterExtensionInfo");
448
+ break;
449
+ case TupleDefinitionType.File:
450
+ set.Add("InstallExecuteSequence/InstallFiles");
451
+ set.Add("InstallExecuteSequence/RemoveFiles");
452
+ break;
453
+ case TupleDefinitionType.Font:
454
+ set.Add("InstallExecuteSequence/RegisterFonts");
455
+ set.Add("InstallExecuteSequence/UnregisterFonts");
456
+ break;
457
+ case TupleDefinitionType.IniFile:
458
+ case TupleDefinitionType.RemoveIniFile:
459
+ set.Add("InstallExecuteSequence/WriteIniValues");
460
+ set.Add("InstallExecuteSequence/RemoveIniValues");
461
+ break;
462
+ case TupleDefinitionType.IsolatedComponent:
463
+ set.Add("InstallExecuteSequence/IsolateComponents");
464
+ break;
465
+ case TupleDefinitionType.LaunchCondition:
466
+ set.Add("InstallExecuteSequence/LaunchConditions");
467
+ set.Add("InstallUISequence/LaunchConditions");
468
+ break;
469
+ case TupleDefinitionType.MIME:
470
+ set.Add("AdvtExecuteSequence/RegisterMIMEInfo");
471
+ set.Add("InstallExecuteSequence/RegisterMIMEInfo");
472
+ set.Add("InstallExecuteSequence/UnregisterMIMEInfo");
473
+ break;
474
+ case TupleDefinitionType.MoveFile:
475
+ set.Add("InstallExecuteSequence/MoveFiles");
476
+ break;
477
+ case TupleDefinitionType.MsiAssembly:
478
+ set.Add("AdvtExecuteSequence/MsiPublishAssemblies");
479
+ set.Add("InstallExecuteSequence/MsiPublishAssemblies");
480
+ set.Add("InstallExecuteSequence/MsiUnpublishAssemblies");
481
+ break;
482
+ case TupleDefinitionType.MsiServiceConfig:
483
+ case TupleDefinitionType.MsiServiceConfigFailureActions:
484
+ set.Add("InstallExecuteSequence/MsiConfigureServices");
485
+ break;
486
+ case TupleDefinitionType.ODBCDataSource:
487
+ case TupleDefinitionType.ODBCTranslator:
488
+ case TupleDefinitionType.ODBCDriver:
489
+ set.Add("InstallExecuteSequence/SetODBCFolders");
490
+ set.Add("InstallExecuteSequence/InstallODBC");
491
+ set.Add("InstallExecuteSequence/RemoveODBC");
492
+ break;
493
+ case TupleDefinitionType.ProgId:
494
+ set.Add("AdvtExecuteSequence/RegisterProgIdInfo");
495
+ set.Add("InstallExecuteSequence/RegisterProgIdInfo");
496
+ set.Add("InstallExecuteSequence/UnregisterProgIdInfo");
497
+ break;
498
+ case TupleDefinitionType.PublishComponent:
499
+ set.Add("AdvtExecuteSequence/PublishComponents");
500
+ set.Add("InstallExecuteSequence/PublishComponents");
501
+ set.Add("InstallExecuteSequence/UnpublishComponents");
502
+ break;
503
+ case TupleDefinitionType.Registry:
504
+ case TupleDefinitionType.RemoveRegistry:
505
+ set.Add("InstallExecuteSequence/WriteRegistryValues");
506
+ set.Add("InstallExecuteSequence/RemoveRegistryValues");
507
+ break;
508
+ case TupleDefinitionType.RemoveFile:
509
+ set.Add("InstallExecuteSequence/RemoveFiles");
510
+ break;
511
+ case TupleDefinitionType.SelfReg:
512
+ set.Add("InstallExecuteSequence/SelfRegModules");
513
+ set.Add("InstallExecuteSequence/SelfUnregModules");
514
+ break;
515
+ case TupleDefinitionType.ServiceControl:
516
+ set.Add("InstallExecuteSequence/StartServices");
517
+ set.Add("InstallExecuteSequence/StopServices");
518
+ set.Add("InstallExecuteSequence/DeleteServices");
519
+ break;
520
+ case TupleDefinitionType.ServiceInstall:
521
+ set.Add("InstallExecuteSequence/InstallServices");
522
+ break;
523
+ case TupleDefinitionType.Shortcut:
524
+ set.Add("AdvtExecuteSequence/CreateShortcuts");
525
+ set.Add("InstallExecuteSequence/CreateShortcuts");
526
+ set.Add("InstallExecuteSequence/RemoveShortcuts");
527
+ break;
528
+ case TupleDefinitionType.TypeLib:
529
+ set.Add("InstallExecuteSequence/RegisterTypeLibraries");
530
+ set.Add("InstallExecuteSequence/UnregisterTypeLibraries");
531
+ break;
532
+ case TupleDefinitionType.Upgrade:
533
+ set.Add("InstallExecuteSequence/FindRelatedProducts");
534
+ set.Add("InstallUISequence/FindRelatedProducts");
535
+
536
+ // Only add the MigrateFeatureStates action if MigrateFeature attribute is set on
537
+ // at least one UpgradeVersion element.
538
+ if (this.Section.Tuples.OfType<UpgradeTuple>().Any(t => (t.Attributes & MsiInterop.MsidbUpgradeAttributesMigrateFeatures) == MsiInterop.MsidbUpgradeAttributesMigrateFeatures))
539
+ {
540
+ set.Add("InstallExecuteSequence/MigrateFeatureStates");
541
+ set.Add("InstallUISequence/MigrateFeatureStates");
542
+ }
543
+ break;
544
+ }
545
+ }
546
+
547
+ return set;
548
+ }
549
+
550
+ private IEnumerable<WixActionTuple> GetActions(SequenceTable sequence, string[] actionNames)
551
+ {
552
+ foreach (var action in WindowsInstallerStandard.StandardActions())
553
+ {
554
+ if (action.SequenceTable == sequence && actionNames.Contains(action.Action))
555
+ {
556
+ yield return action;
557
+ }
558
+ }
559
+ }
560
+
561
+ /// <summary>
562
+ /// Sequence an action before or after a standard action.
563
+ /// </summary>
564
+ /// <param name="actionRow">The action row to be sequenced.</param>
565
+ /// <param name="requiredActionRows">Collection of actions which must be included.</param>
566
+ private void SequenceActionRow(WixActionTuple actionRow, Dictionary<string, WixActionTuple> requiredActionRows)
567
+ {
568
+ var after = false;
569
+
570
+ if (actionRow.After != null)
571
+ {
572
+ after = true;
573
+ }
574
+ else if (actionRow.Before == null)
575
+ {
576
+ throw new InvalidOperationException(WixStrings.EXP_FoundActionRowWithNoSequenceBeforeOrAfterColumnSet);
577
+ }
578
+
579
+ var parentActionName = (after ? actionRow.After : actionRow.Before);
580
+ var parentActionKey = actionRow.SequenceTable.ToString() + "/" + parentActionName;
581
+
582
+ if (!requiredActionRows.TryGetValue(parentActionKey, out var parentActionRow))
583
+ {
584
+ // If the missing parent action is a standard action (with a suggested sequence number), add it.
585
+ if (this.StandardActionsById.TryGetValue(parentActionKey, out parentActionRow))
586
+ {
587
+ // Create a clone to avoid modifying the static copy of the object.
588
+ // TODO: consider this: parentActionRow = parentActionRow.Clone();
589
+
590
+ requiredActionRows.Add(parentActionRow.Id.Id, parentActionRow);
591
+ }
592
+ else
593
+ {
594
+ throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_FoundActionRowWinNonExistentAction, (after ? "After" : "Before"), parentActionName));
595
+ }
596
+ }
597
+ else if (actionRow == parentActionRow || this.ContainsChildActionRow(actionRow, parentActionRow)) // cycle detected
598
+ {
599
+ throw new WixException(WixErrors.ActionCircularDependency(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, parentActionRow.Action));
600
+ }
601
+
602
+ // Add this action to the appropriate list of dependent action rows.
603
+ var relativeActions = this.GetRelativeActions(parentActionRow);
604
+ var relatedRows = (after ? relativeActions.NextActions : relativeActions.PreviousActions);
605
+ relatedRows.Add(actionRow);
606
+ }
607
+
608
+ private bool ContainsChildActionRow(WixActionTuple childTuple, WixActionTuple parentTuple)
609
+ {
610
+ var result = false;
611
+
612
+ if (this.RelativeActionsForActions.TryGetValue(childTuple.Id.Id, out var relativeActions))
613
+ {
614
+ result = relativeActions.NextActions.Any(a => a.SequenceTable == parentTuple.SequenceTable && a.Id.Id == parentTuple.Id.Id) ||
615
+ relativeActions.PreviousActions.Any(a => a.SequenceTable == parentTuple.SequenceTable && a.Id.Id == parentTuple.Id.Id);
616
+ }
617
+
618
+ return result;
619
+ }
620
+
621
+ private RelativeActions GetRelativeActions(WixActionTuple action)
622
+ {
623
+ if (!this.RelativeActionsForActions.TryGetValue(action.Id.Id, out var relativeActions))
624
+ {
625
+ relativeActions = new RelativeActions();
626
+ this.RelativeActionsForActions.Add(action.Id.Id, relativeActions);
627
+ }
628
+
629
+ return relativeActions;
630
+ }
631
+
632
+ private RelativeActions GetAllRelativeActionsForSequenceType(SequenceTable sequenceType, WixActionTuple action)
633
+ {
634
+ var relativeActions = new RelativeActions();
635
+
636
+ if (this.RelativeActionsForActions.TryGetValue(action.Id.Id, out var actionRelatives))
637
+ {
638
+ this.RecurseRelativeActionsForSequenceType(sequenceType, actionRelatives.PreviousActions, relativeActions.PreviousActions);
639
+
640
+ this.RecurseRelativeActionsForSequenceType(sequenceType, actionRelatives.NextActions, relativeActions.NextActions);
641
+ }
642
+
643
+ return relativeActions;
644
+ }
645
+
646
+ private void RecurseRelativeActionsForSequenceType(SequenceTable sequenceType, List<WixActionTuple> actions, List<WixActionTuple> visitedActions)
647
+ {
648
+ foreach (var action in actions.Where(a => a.SequenceTable == sequenceType))
649
+ {
650
+ if (this.RelativeActionsForActions.TryGetValue(action.Id.Id, out var actionRelatives))
651
+ {
652
+ this.RecurseRelativeActionsForSequenceType(sequenceType, actionRelatives.PreviousActions, visitedActions);
653
+ }
654
+
655
+ visitedActions.Add(action);
656
+
657
+ if (actionRelatives != null)
658
+ {
659
+ this.RecurseRelativeActionsForSequenceType(sequenceType, actionRelatives.NextActions, visitedActions);
660
+ }
661
+ }
662
+ }
663
+
664
+ private class RelativeActions
665
+ {
666
+ public List<WixActionTuple> PreviousActions { get; } = new List<WixActionTuple>();
667
+
668
+ public List<WixActionTuple> NextActions { get; } = new List<WixActionTuple>();
669
+ }
670
+ }
671
+}
src/WixToolset.Core.WindowsInstaller/Bind/UpdateControlTextCommand.cs
+1
-1
@@ -1,6 +1,6 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
using System.IO;
src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs
+49
-63
@@ -1,10 +1,9 @@
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.Databases
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
{
5
using System;
6
using System.Collections.Generic;
7
- using System.Collections.Specialized;
7
using System.ComponentModel;
8
using System.Globalization;
9
using System.IO;
@@ -14,7 +13,6 @@ namespace WixToolset.Core.WindowsInstaller.Databases
13
using WixToolset.Clr.Interop;
14
using WixToolset.Core.Bind;
15
using WixToolset.Data;
17
- using WixToolset.Data.Rows;
16
using WixToolset.Data.Tuples;
17
using WixToolset.Msi;
18
@@ -23,13 +21,16 @@ namespace WixToolset.Core.WindowsInstaller.Databases
21
/// </summary>
22
internal class UpdateFileFacadesCommand
23
{
26
- public IEnumerable<FileFacade> FileFacades { private get; set; }
24
+ public UpdateFileFacadesCommand(IntermediateSection section)
25
+ {
26
+ this.Section = section;
27
+ }
28
28
- public IEnumerable<FileFacade> UpdateFileFacades { private get; set; }
29
+ private IntermediateSection Section { get; }
30
30
- public string ModularizationGuid { private get; set; }
31
+ public IEnumerable<FileFacade> FileFacades { private get; set; }
32
32
- public Output Output { private get; set; }
33
+ public IEnumerable<FileFacade> UpdateFileFacades { private get; set; }
34
35
public bool OverwriteHash { private get; set; }
36
@@ -47,6 +48,12 @@ namespace WixToolset.Core.WindowsInstaller.Databases
48
49
private void UpdateFileFacade(FileFacade file)
50
{
51
+ var assemblyNameTuples = new Dictionary<string, MsiAssemblyNameTuple>();
52
+ foreach (var assemblyTuple in this.Section.Tuples.OfType<MsiAssemblyNameTuple>())
53
+ {
54
+ assemblyNameTuples.Add(assemblyTuple.Component_ + "/" + assemblyTuple.Name, assemblyTuple);
55
+ }
56
+
57
FileInfo fileInfo = null;
58
try
59
{
@@ -149,9 +156,8 @@ namespace WixToolset.Core.WindowsInstaller.Databases
156
157
if (null == file.Hash)
158
{
152
- //Table msiFileHashTable = this.Output.EnsureTable(this.TableDefinitions["MsiFileHash"]);
153
- //file.Hash = msiFileHashTable.CreateRow(file.File.SourceLineNumbers);
154
- throw new NotImplementedException();
159
+ file.Hash = new MsiFileHashTuple(file.File.SourceLineNumbers, file.File.Id);
160
+ this.Section.Tuples.Add(file.Hash);
161
}
162
163
file.Hash.File_ = file.File.File;
@@ -198,13 +204,13 @@ namespace WixToolset.Core.WindowsInstaller.Databases
204
{
205
if (!String.IsNullOrEmpty(file.File.Version))
206
{
201
- string key = String.Format(CultureInfo.InvariantCulture, "fileversion.{0}", Common.Demodularize(this.Output.Type, this.ModularizationGuid, file.File.File));
207
+ var key = String.Format(CultureInfo.InvariantCulture, "fileversion.{0}", file.File.File);
208
this.VariableCache[key] = file.File.Version;
209
}
210
211
if (!String.IsNullOrEmpty(file.File.Language))
212
{
207
- string key = String.Format(CultureInfo.InvariantCulture, "filelanguage.{0}", Common.Demodularize(this.Output.Type, ModularizationGuid, file.File.File));
213
+ var key = String.Format(CultureInfo.InvariantCulture, "filelanguage.{0}", file.File.File);
214
this.VariableCache[key] = file.File.Language;
215
}
216
}
@@ -214,14 +220,13 @@ namespace WixToolset.Core.WindowsInstaller.Databases
220
if (FileAssemblyType.DotNetAssembly == file.WixFile.AssemblyType)
221
{
222
bool targetNetfx1 = false;
217
- StringDictionary assemblyNameValues = new StringDictionary();
223
+ var assemblyNameValues = new Dictionary<string, string>();
224
219
- ClrInterop.IReferenceIdentity referenceIdentity = null;
225
Guid referenceIdentityGuid = ClrInterop.ReferenceIdentityGuid;
221
- uint result = ClrInterop.GetAssemblyIdentityFromFile(fileInfo.FullName, ref referenceIdentityGuid, out referenceIdentity);
226
+ var result = ClrInterop.GetAssemblyIdentityFromFile(fileInfo.FullName, ref referenceIdentityGuid, out var referenceIdentity);
227
if (0 == result && null != referenceIdentity)
228
{
224
- string imageRuntimeVersion = referenceIdentity.GetAttribute(null, "ImageRuntimeVersion");
229
+ var imageRuntimeVersion = referenceIdentity.GetAttribute(null, "ImageRuntimeVersion");
230
if (null != imageRuntimeVersion)
231
{
232
targetNetfx1 = imageRuntimeVersion.StartsWith("v1", StringComparison.OrdinalIgnoreCase);
@@ -269,15 +274,14 @@ namespace WixToolset.Core.WindowsInstaller.Databases
274
return;
275
}
276
272
- Table assemblyNameTable = this.Output.EnsureTable(this.TableDefinitions["MsiAssemblyName"]);
273
- if (assemblyNameValues.ContainsKey("name"))
277
+ if (assemblyNameValues.TryGetValue("name", out var value))
278
{
275
- this.SetMsiAssemblyName(assemblyNameTable, file, "name", assemblyNameValues["name"]);
279
+ this.SetMsiAssemblyName(assemblyNameTuples, file, "name", value);
280
}
281
282
if (!String.IsNullOrEmpty(version))
283
{
280
- this.SetMsiAssemblyName(assemblyNameTable, file, "fileVersion", version);
284
+ this.SetMsiAssemblyName(assemblyNameTuples, file, "fileVersion", version);
285
}
286
287
if (assemblyNameValues.ContainsKey("version"))
@@ -303,33 +307,33 @@ namespace WixToolset.Core.WindowsInstaller.Databases
307
}
308
}
309
306
- this.SetMsiAssemblyName(assemblyNameTable, file, "version", assemblyVersion);
310
+ this.SetMsiAssemblyName(assemblyNameTuples, file, "version", assemblyVersion);
311
}
312
313
if (assemblyNameValues.ContainsKey("culture"))
314
{
311
- this.SetMsiAssemblyName(assemblyNameTable, file, "culture", assemblyNameValues["culture"]);
315
+ this.SetMsiAssemblyName(assemblyNameTuples, file, "culture", assemblyNameValues["culture"]);
316
}
317
318
if (assemblyNameValues.ContainsKey("publicKeyToken"))
319
{
316
- this.SetMsiAssemblyName(assemblyNameTable, file, "publicKeyToken", assemblyNameValues["publicKeyToken"]);
320
+ this.SetMsiAssemblyName(assemblyNameTuples, file, "publicKeyToken", assemblyNameValues["publicKeyToken"]);
321
}
322
323
if (!String.IsNullOrEmpty(file.WixFile.ProcessorArchitecture))
324
{
321
- this.SetMsiAssemblyName(assemblyNameTable, file, "processorArchitecture", file.WixFile.ProcessorArchitecture);
325
+ this.SetMsiAssemblyName(assemblyNameTuples, file, "processorArchitecture", file.WixFile.ProcessorArchitecture);
326
}
327
328
if (assemblyNameValues.ContainsKey("processorArchitecture"))
329
{
326
- this.SetMsiAssemblyName(assemblyNameTable, file, "processorArchitecture", assemblyNameValues["processorArchitecture"]);
330
+ this.SetMsiAssemblyName(assemblyNameTuples, file, "processorArchitecture", assemblyNameValues["processorArchitecture"]);
331
}
332
333
// add the assembly name to the information cache
334
if (null != this.VariableCache)
335
{
332
- string fileId = Common.Demodularize(this.Output.Type, this.ModularizationGuid, file.File.File);
336
+ string fileId = file.File.File;
337
string key = String.Concat("assemblyfullname.", fileId);
338
string assemblyName = String.Concat(assemblyNameValues["name"], ", version=", assemblyNameValues["version"], ", culture=", assemblyNameValues["culture"], ", publicKeyToken=", String.IsNullOrEmpty(assemblyNameValues["publicKeyToken"]) ? "null" : assemblyNameValues["publicKeyToken"]);
339
if (assemblyNameValues.ContainsKey("processorArchitecture"))
@@ -437,30 +441,29 @@ namespace WixToolset.Core.WindowsInstaller.Databases
441
Messaging.Instance.OnMessage(WixErrors.InvalidXml(new SourceLineNumber(fileManifest.WixFile.Source), "manifest", xe.Message));
442
}
443
440
- Table assemblyNameTable = this.Output.EnsureTable(this.TableDefinitions["MsiAssemblyName"]);
444
if (!String.IsNullOrEmpty(win32Name))
445
{
443
- this.SetMsiAssemblyName(assemblyNameTable, file, "name", win32Name);
446
+ this.SetMsiAssemblyName(assemblyNameTuples, file, "name", win32Name);
447
}
448
449
if (!String.IsNullOrEmpty(win32Version))
450
{
448
- this.SetMsiAssemblyName(assemblyNameTable, file, "version", win32Version);
451
+ this.SetMsiAssemblyName(assemblyNameTuples, file, "version", win32Version);
452
}
453
454
if (!String.IsNullOrEmpty(win32Type))
455
{
453
- this.SetMsiAssemblyName(assemblyNameTable, file, "type", win32Type);
456
+ this.SetMsiAssemblyName(assemblyNameTuples, file, "type", win32Type);
457
}
458
459
if (!String.IsNullOrEmpty(win32ProcessorArchitecture))
460
{
458
- this.SetMsiAssemblyName(assemblyNameTable, file, "processorArchitecture", win32ProcessorArchitecture);
461
+ this.SetMsiAssemblyName(assemblyNameTuples, file, "processorArchitecture", win32ProcessorArchitecture);
462
}
463
464
if (!String.IsNullOrEmpty(win32PublicKeyToken))
465
{
463
- this.SetMsiAssemblyName(assemblyNameTable, file, "publicKeyToken", win32PublicKeyToken);
466
+ this.SetMsiAssemblyName(assemblyNameTuples, file, "publicKeyToken", win32PublicKeyToken);
467
}
468
}
469
}
@@ -469,11 +472,11 @@ namespace WixToolset.Core.WindowsInstaller.Databases
472
/// Set an MsiAssemblyName row. If it was directly authored, override the value, otherwise
473
/// create a new row.
474
/// </summary>
472
- /// <param name="assemblyNameTable">MsiAssemblyName table.</param>
475
+ /// <param name="assemblyNameTuples">MsiAssemblyName table.</param>
476
/// <param name="file">FileFacade containing the assembly read for the MsiAssemblyName row.</param>
477
/// <param name="name">MsiAssemblyName name.</param>
478
/// <param name="value">MsiAssemblyName value.</param>
476
- private void SetMsiAssemblyName(Table assemblyNameTable, FileFacade file, string name, string value)
479
+ private void SetMsiAssemblyName(Dictionary<string, MsiAssemblyNameTuple> assemblyNameTuples, FileFacade file, string name, string value)
480
{
481
// check for null value (this can occur when grabbing the file version from an assembly without one)
482
if (String.IsNullOrEmpty(value))
@@ -482,18 +485,6 @@ namespace WixToolset.Core.WindowsInstaller.Databases
485
}
486
else
487
{
485
- Row assemblyNameRow = null;
486
-
487
- // override directly authored value
488
- foreach (Row row in assemblyNameTable.Rows)
489
- {
490
- if ((string)row[0] == file.File.Component_ && (string)row[1] == name)
491
- {
492
- assemblyNameRow = row;
493
- break;
494
- }
495
- }
496
-
488
// if the assembly will be GAC'd and the name in the file table doesn't match the name in the MsiAssemblyName table, error because the install will fail.
489
if ("name" == name && FileAssemblyType.DotNetAssembly == file.WixFile.AssemblyType &&
490
String.IsNullOrEmpty(file.WixFile.File_AssemblyApplication) &&
@@ -502,17 +493,14 @@ namespace WixToolset.Core.WindowsInstaller.Databases
493
Messaging.Instance.OnMessage(WixErrors.GACAssemblyIdentityWarning(file.File.SourceLineNumbers, Path.GetFileNameWithoutExtension(file.File.LongFileName), value));
494
}
495
505
- if (null == assemblyNameRow)
496
+ // override directly authored value
497
+ var lookup = String.Concat(file.File.Component_, "/", name);
498
+ if (assemblyNameTuples.TryGetValue(lookup, out var assemblyNameRow))
499
{
507
- throw new NotImplementedException();
508
-#if TODO
509
- assemblyNameRow = assemblyNameTable.CreateRow(file.File.SourceLineNumbers);
510
- assemblyNameRow[0] = file.File.Component_;
511
- assemblyNameRow[1] = name;
512
- assemblyNameRow[2] = value;
513
-
514
- // put the MsiAssemblyName row in the same section as the related File row
515
- assemblyNameRow.SectionId = file.File.SectionId;
500
+ assemblyNameRow = new MsiAssemblyNameTuple(file.File.SourceLineNumbers);
501
+ assemblyNameRow.Component_ = file.File.Component_;
502
+ assemblyNameRow.Name = name;
503
+ assemblyNameRow.Value = value;
504
505
if (null == file.AssemblyNames)
506
{
@@ -520,17 +508,15 @@ namespace WixToolset.Core.WindowsInstaller.Databases
508
}
509
510
file.AssemblyNames.Add(assemblyNameRow);
523
-#endif
524
- }
525
- else
526
- {
527
- assemblyNameRow[2] = value;
511
+ this.Section.Tuples.Add(assemblyNameRow);
512
}
513
514
+ assemblyNameRow.Value = value;
515
+
516
if (this.VariableCache != null)
517
{
532
- string key = String.Format(CultureInfo.InvariantCulture, "assembly{0}.{1}", name, Common.Demodularize(this.Output.Type, this.ModularizationGuid, file.File.File)).ToLowerInvariant();
533
- this.VariableCache[key] = (string)assemblyNameRow[2];
518
+ var key = String.Format(CultureInfo.InvariantCulture, "assembly{0}.{1}", name, file.File.File).ToLowerInvariant();
519
+ this.VariableCache[key] = value;
520
}
521
}
522
}
src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs
new
+126
@@ -0,0 +1,126 @@
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.Linq;
8
+ using WixToolset.Core.Bind;
9
+ using WixToolset.Data;
10
+ using WixToolset.Data.Rows;
11
+ using WixToolset.Data.Tuples;
12
+
13
+ internal class UpdateMediaSequencesCommand
14
+ {
15
+ public UpdateMediaSequencesCommand(Output output, List<FileFacade> fileFacades, Dictionary<int, MediaTuple> assignedMediaRows)
16
+ {
17
+ this.Output = output;
18
+ this.FileFacades = fileFacades;
19
+ }
20
+
21
+ private Output Output { get; }
22
+
23
+ private List<FileFacade> FileFacades { get; }
24
+
25
+ public void Execute()
26
+ {
27
+ var fileRows = new RowDictionary<FileRow>(this.Output.Tables["File"]);
28
+ var mediaRows = new RowDictionary<MediaRow>(this.Output.Tables["Media"]);
29
+
30
+ // Calculate sequence numbers and media disk id layout for all file media information objects.
31
+ if (OutputType.Module == this.Output.Type)
32
+ {
33
+ var lastSequence = 0;
34
+
35
+ // Order by Component to group the files by directory.
36
+ var optimized = this.OptimizedFileFacades();
37
+ foreach (var fileId in optimized.Select(f => f.File.File))
38
+ {
39
+ var fileRow = fileRows.Get(fileId);
40
+ fileRow.Sequence = ++lastSequence;
41
+ }
42
+ }
43
+ else
44
+ {
45
+ int lastSequence = 0;
46
+ MediaRow mediaRow = null;
47
+ Dictionary<int, List<FileFacade>> patchGroups = new Dictionary<int, List<FileFacade>>();
48
+
49
+ // sequence the non-patch-added files
50
+ var optimized = this.OptimizedFileFacades();
51
+ foreach (FileFacade facade in optimized)
52
+ {
53
+ if (null == mediaRow)
54
+ {
55
+ mediaRow = mediaRows.Get(facade.WixFile.DiskId);
56
+ if (OutputType.Patch == this.Output.Type)
57
+ {
58
+ // patch Media cannot start at zero
59
+ lastSequence = mediaRow.LastSequence;
60
+ }
61
+ }
62
+ else if (mediaRow.DiskId != facade.WixFile.DiskId)
63
+ {
64
+ mediaRow.LastSequence = lastSequence;
65
+ mediaRow = mediaRows.Get(facade.WixFile.DiskId);
66
+ }
67
+
68
+ if (0 < facade.WixFile.PatchGroup)
69
+ {
70
+ if (patchGroups.TryGetValue(facade.WixFile.PatchGroup, out var patchGroup))
71
+ {
72
+ patchGroup = new List<FileFacade>();
73
+ patchGroups.Add(facade.WixFile.PatchGroup, patchGroup);
74
+ }
75
+
76
+ patchGroup.Add(facade);
77
+ }
78
+ else
79
+ {
80
+ var fileRow = fileRows.Get(facade.File.File);
81
+ fileRow.Sequence = ++lastSequence;
82
+ }
83
+ }
84
+
85
+ if (null != mediaRow)
86
+ {
87
+ mediaRow.LastSequence = lastSequence;
88
+ mediaRow = null;
89
+ }
90
+
91
+ // sequence the patch-added files
92
+ foreach (var patchGroup in patchGroups.Values)
93
+ {
94
+ foreach (var facade in patchGroup)
95
+ {
96
+ if (null == mediaRow)
97
+ {
98
+ mediaRow = mediaRows.Get(facade.WixFile.DiskId);
99
+ }
100
+ else if (mediaRow.DiskId != facade.WixFile.DiskId)
101
+ {
102
+ mediaRow.LastSequence = lastSequence;
103
+ mediaRow = mediaRows.Get(facade.WixFile.DiskId);
104
+ }
105
+
106
+ var fileRow = fileRows.Get(facade.File.File);
107
+ fileRow.Sequence = ++lastSequence;
108
+ }
109
+ }
110
+
111
+ if (null != mediaRow)
112
+ {
113
+ mediaRow.LastSequence = lastSequence;
114
+ }
115
+ }
116
+ }
117
+
118
+ private IEnumerable<FileFacade> OptimizedFileFacades()
119
+ {
120
+ // TODO: Sort these facades even smarter by directory path and component id
121
+ // and maybe file size or file extension and other creative ideas to
122
+ // get optimal install speed out of MSI.
123
+ return this.FileFacades.OrderBy(f => f.File.Component_);
124
+ }
125
+ }
126
+}
src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs
+1
-1
@@ -18,7 +18,7 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe
18
public InscribeMsiPackageCommand(IInscribeContext context)
19
{
20
this.Context = context;
21
- this.TableDefinitions = WindowsInstallerStandard.GetTableDefinitions();
21
+ this.TableDefinitions = WindowsInstallerStandardInternal.GetTableDefinitions();
22
}
23
24
private IInscribeContext Context { get; }
src/WixToolset.Core.WindowsInstaller/MstBackend.cs
-1
@@ -3,7 +3,6 @@
3
namespace WixToolset.Core.WindowsInstaller
4
{
5
using System;
6
- using WixToolset.Core.WindowsInstaller.Databases;
6
using WixToolset.Core.WindowsInstaller.Unbind;
7
using WixToolset.Data;
8
using WixToolset.Data.Bind;
src/WixToolset.Core.WindowsInstaller/Patch.cs
+1
-1
@@ -29,7 +29,7 @@ namespace WixToolset.Data
29
public Patch()
30
{
31
this.inspectorExtensions = new List<IInspectorExtension>();
32
- this.tableDefinitions = new TableDefinitionCollection(WindowsInstallerStandard.GetTableDefinitions());
32
+ this.tableDefinitions = new TableDefinitionCollection(WindowsInstallerStandardInternal.GetTableDefinitions());
33
}
34
35
/// <summary>
src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs
+1
-1
@@ -27,7 +27,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
27
this.SuppressDemodularization = suppressDemodularization;
28
this.SkipSummaryInfo = skipSummaryInfo;
29
30
- this.TableDefinitions = WindowsInstallerStandard.GetTableDefinitions();
30
+ this.TableDefinitions = WindowsInstallerStandardInternal.GetTableDefinitions();
31
}
32
33
public Messaging Messaging { get; }
src/WixToolset.Core.WindowsInstaller/Unbind/UnbindTranformCommand.cs
+2
-5
@@ -4,16 +4,13 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
4
{
5
using System;
6
using System.Collections;
7
- using System.Collections.Generic;
7
using System.ComponentModel;
8
using System.Globalization;
9
using System.IO;
10
using System.Linq;
12
- using System.Text.RegularExpressions;
11
using WixToolset.Core.Native;
14
- using WixToolset.Core.WindowsInstaller.Databases;
12
+ using WixToolset.Core.WindowsInstaller.Bind;
13
using WixToolset.Data;
16
- using WixToolset.Data.Rows;
14
using WixToolset.Extensibility;
15
using WixToolset.Msi;
16
@@ -26,7 +23,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
23
this.ExportBasePath = exportBasePath;
24
this.IntermediateFolder = intermediateFolder;
25
29
- this.TableDefinitions = WindowsInstallerStandard.GetTableDefinitions();
26
+ this.TableDefinitions = WindowsInstallerStandardInternal.GetTableDefinitions();
27
}
28
29
private Messaging Messaging { get; }
src/WixToolset.Core/Bind/ExtractEmbeddedFilesCommand.cs
+10
-5
@@ -11,7 +11,12 @@ namespace WixToolset.Core.Bind
11
12
public class ExtractEmbeddedFilesCommand
13
{
14
- public IEnumerable<IExpectedExtractFile> FilesWithEmbeddedFiles { private get; set; }
14
+ public ExtractEmbeddedFilesCommand(IEnumerable<IExpectedExtractFile> embeddedFiles)
15
+ {
16
+ this.FilesWithEmbeddedFiles = embeddedFiles;
17
+ }
18
+
19
+ private IEnumerable<IExpectedExtractFile> FilesWithEmbeddedFiles { get; }
20
21
public void Execute()
22
{
@@ -28,10 +33,10 @@ namespace WixToolset.Core.Bind
33
// a .wixlib embedded in a WixExtension).
34
if ("embeddedresource" == baseUri.Scheme)
35
{
31
- string assemblyPath = Path.GetFullPath(baseUri.LocalPath);
32
- string resourceName = baseUri.Fragment.TrimStart('#');
36
+ var assemblyPath = Path.GetFullPath(baseUri.LocalPath);
37
+ var resourceName = baseUri.Fragment.TrimStart('#');
38
34
- Assembly assembly = Assembly.LoadFile(assemblyPath);
39
+ var assembly = Assembly.LoadFile(assemblyPath);
40
stream = assembly.GetManifestResourceStream(resourceName);
41
}
42
else // normal file (usually a binary .wixlib on disk).
@@ -39,7 +44,7 @@ namespace WixToolset.Core.Bind
44
stream = File.OpenRead(baseUri.LocalPath);
45
}
46
42
- using (FileStructure fs = FileStructure.Read(stream))
47
+ using (var fs = FileStructure.Read(stream))
48
{
49
var uniqueIndicies = new SortedSet<int>();
50
src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs
+34
-44
@@ -12,25 +12,28 @@ namespace WixToolset.Core.Bind
12
/// Resolves the fields which had variables that needed to be resolved after the file information
13
/// was loaded.
14
/// </summary>
15
- public class ResolveDelayedFieldsCommand : ICommand
15
+ public class ResolveDelayedFieldsCommand
16
{
17
- public OutputType OutputType { private get; set;}
18
-
19
- public IEnumerable<IDelayedField> DelayedFields { private get; set;}
17
+ /// <summary>
18
+ /// Resolve delayed fields.
19
+ /// </summary>
20
+ /// <param name="delayedFields">The fields which had resolution delayed.</param>
21
+ /// <param name="variableCache">The file information to use when resolving variables.</param>
22
+ public ResolveDelayedFieldsCommand(IEnumerable<IDelayedField> delayedFields, Dictionary<string, string> variableCache)
23
+ {
24
+ this.DelayedFields = delayedFields;
25
+ this.VariableCache = variableCache;
26
+ }
27
21
- public IDictionary<string, string> VariableCache { private get; set; }
28
+ private IEnumerable<IDelayedField> DelayedFields { get;}
29
23
- public string ModularizationGuid { private get; set; }
30
+ private IDictionary<string, string> VariableCache { get; }
31
25
- /// <param name="output">Internal representation of the msi database to operate upon.</param>
26
- /// <param name="delayedFields">The fields which had resolution delayed.</param>
27
- /// <param name="variableCache">The file information to use when resolving variables.</param>
28
- /// <param name="modularizationGuid">The modularization guid (used in case of a merge module).</param>
32
public void Execute()
33
{
34
var deferredFields = new List<IDelayedField>();
35
33
- foreach (IDelayedField delayedField in this.DelayedFields)
36
+ foreach (var delayedField in this.DelayedFields)
37
{
38
try
39
{
@@ -42,7 +45,7 @@ namespace WixToolset.Core.Bind
45
var value = WixVariableResolver.ResolveDelayedVariables(propertyRow.SourceLineNumbers, delayedField.Field.AsString(), this.VariableCache);
46
47
// update the variable cache with the new value
45
- var key = String.Concat("property.", Common.Demodularize(this.OutputType, this.ModularizationGuid, (string)propertyRow[0]));
48
+ var key = String.Concat("property.", propertyRow.AsString(0));
49
this.VariableCache[key] = value;
50
51
// update the field data
@@ -62,43 +65,31 @@ namespace WixToolset.Core.Bind
65
66
// add specialization for ProductVersion fields
67
string keyProductVersion = "property.ProductVersion";
65
- if (this.VariableCache.ContainsKey(keyProductVersion))
68
+ if (this.VariableCache.TryGetValue(keyProductVersion, out var versionValue) && Version.TryParse(versionValue, out Version productVersion))
69
{
67
- string value = this.VariableCache[keyProductVersion];
68
- Version productVersion = null;
69
-
70
- try
70
+ // Don't add the variable if it already exists (developer defined a property with the same name).
71
+ string fieldKey = String.Concat(keyProductVersion, ".Major");
72
+ if (!this.VariableCache.ContainsKey(fieldKey))
73
{
72
- productVersion = new Version(value);
73
-
74
- // Don't add the variable if it already exists (developer defined a property with the same name).
75
- string fieldKey = String.Concat(keyProductVersion, ".Major");
76
- if (!this.VariableCache.ContainsKey(fieldKey))
77
- {
78
- this.VariableCache[fieldKey] = productVersion.Major.ToString(CultureInfo.InvariantCulture);
79
- }
80
-
81
- fieldKey = String.Concat(keyProductVersion, ".Minor");
82
- if (!this.VariableCache.ContainsKey(fieldKey))
83
- {
84
- this.VariableCache[fieldKey] = productVersion.Minor.ToString(CultureInfo.InvariantCulture);
85
- }
74
+ this.VariableCache[fieldKey] = productVersion.Major.ToString(CultureInfo.InvariantCulture);
75
+ }
76
87
- fieldKey = String.Concat(keyProductVersion, ".Build");
88
- if (!this.VariableCache.ContainsKey(fieldKey))
89
- {
90
- this.VariableCache[fieldKey] = productVersion.Build.ToString(CultureInfo.InvariantCulture);
91
- }
77
+ fieldKey = String.Concat(keyProductVersion, ".Minor");
78
+ if (!this.VariableCache.ContainsKey(fieldKey))
79
+ {
80
+ this.VariableCache[fieldKey] = productVersion.Minor.ToString(CultureInfo.InvariantCulture);
81
+ }
82
93
- fieldKey = String.Concat(keyProductVersion, ".Revision");
94
- if (!this.VariableCache.ContainsKey(fieldKey))
95
- {
96
- this.VariableCache[fieldKey] = productVersion.Revision.ToString(CultureInfo.InvariantCulture);
97
- }
83
+ fieldKey = String.Concat(keyProductVersion, ".Build");
84
+ if (!this.VariableCache.ContainsKey(fieldKey))
85
+ {
86
+ this.VariableCache[fieldKey] = productVersion.Build.ToString(CultureInfo.InvariantCulture);
87
}
99
- catch
88
+
89
+ fieldKey = String.Concat(keyProductVersion, ".Revision");
90
+ if (!this.VariableCache.ContainsKey(fieldKey))
91
{
101
- // Ignore the error introduced by new behavior.
92
+ this.VariableCache[fieldKey] = productVersion.Revision.ToString(CultureInfo.InvariantCulture);
93
}
94
}
95
@@ -113,7 +104,6 @@ namespace WixToolset.Core.Bind
104
catch (WixException we)
105
{
106
Messaging.Instance.OnMessage(we.Error);
116
- continue;
107
}
108
}
109
}
src/WixToolset.Core/Bind/ResolvedDirectory.cs
+9
-9
@@ -7,15 +7,6 @@ namespace WixToolset.Bind
7
/// </summary>
8
public struct ResolvedDirectory
9
{
10
- /// <summary>The directory parent.</summary>
11
- public string DirectoryParent;
12
-
13
- /// <summary>The name of this directory.</summary>
14
- public string Name;
15
-
16
- /// <summary>The path of this directory.</summary>
17
- public string Path;
18
-
10
/// <summary>
11
/// Constructor for ResolvedDirectory.
12
/// </summary>
@@ -27,5 +18,14 @@ namespace WixToolset.Bind
18
this.Name = name;
19
this.Path = null;
20
}
21
+
22
+ /// <summary>The directory parent.</summary>
23
+ public string DirectoryParent { get; set; }
24
+
25
+ /// <summary>The name of this directory.</summary>
26
+ public string Name { get; set; }
27
+
28
+ /// <summary>The path of this directory.</summary>
29
+ public string Path { get; set; }
30
}
31
}
src/WixToolset.Core/Binder.cs
+4
-4
@@ -609,9 +609,9 @@ namespace WixToolset.Core
609
/// <param name="directory">Directory identifier.</param>
610
/// <param name="canonicalize">Canonicalize the path for standard directories.</param>
611
/// <returns>Source path of a directory.</returns>
612
- public static string GetDirectoryPath(Hashtable directories, Hashtable componentIdGenSeeds, string directory, bool canonicalize)
612
+ public static string GetDirectoryPath(Dictionary<string, ResolvedDirectory> directories, Dictionary<string, string> componentIdGenSeeds, string directory, bool canonicalize)
613
{
614
- if (!directories.Contains(directory))
614
+ if (!directories.ContainsKey(directory))
615
{
616
throw new WixException(WixErrors.ExpectedDirectory(directory));
617
}
@@ -620,7 +620,7 @@ namespace WixToolset.Core
620
621
if (null == resolvedDirectory.Path)
622
{
623
- if (null != componentIdGenSeeds && componentIdGenSeeds.Contains(directory))
623
+ if (null != componentIdGenSeeds && componentIdGenSeeds.ContainsKey(directory))
624
{
625
resolvedDirectory.Path = (string)componentIdGenSeeds[directory];
626
}
@@ -670,7 +670,7 @@ namespace WixToolset.Core
670
/// <param name="compressed">Specifies the package is compressed.</param>
671
/// <param name="useLongName">Specifies the package uses long file names.</param>
672
/// <returns>Source path of file relative to package directory.</returns>
673
- public static string GetFileSourcePath(Hashtable directories, string directoryId, string fileName, bool compressed, bool useLongName)
673
+ public static string GetFileSourcePath(Dictionary<string, ResolvedDirectory> directories, string directoryId, string fileName, bool compressed, bool useLongName)
674
{
675
string fileSourcePath = Common.GetName(fileName, true, useLongName);
676
src/WixToolset.Core/Compiler.cs
+4
-4
@@ -7137,7 +7137,7 @@ namespace WixToolset
7137
}
7138
7139
// finally, schedule RemoveExistingProducts
7140
- row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixAction);
7140
+ row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixAction, new Identifier("InstallExecuteSequence/RemoveExistingProducts", AccessModifier.Public));
7141
row.Set(0, "InstallExecuteSequence");
7142
row.Set(1, "RemoveExistingProducts");
7143
// row.Set(2, condition);
@@ -7641,11 +7641,11 @@ namespace WixToolset
7641
row.Set(4, diskId);
7642
if (YesNoType.Yes == fileCompression)
7643
{
7644
- row.Set(5, 1);
7644
+ row.Set(5, true);
7645
}
7646
else if (YesNoType.No == fileCompression)
7647
{
7648
- row.Set(5, 0);
7648
+ row.Set(5, false);
7649
}
7650
else // YesNoType.NotSet == fileCompression
7651
{
@@ -9525,7 +9525,7 @@ namespace WixToolset
9525
var patchIdRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchId);
9526
patchIdRow.Set(0, patchId);
9527
patchIdRow.Set(1, clientPatchId);
9528
- patchIdRow.Set(2, optimizePatchSizeForLargeFiles ? 1 : 0);
9528
+ patchIdRow.Set(2, optimizePatchSizeForLargeFiles);
9529
patchIdRow.Set(3, apiPatchingSymbolFlags);
9530
9531
if (allowRemoval)
src/WixToolset.Core/Linker.cs
+2
-668
@@ -23,9 +23,6 @@ namespace WixToolset.Core
23
private static readonly string emptyGuid = Guid.Empty.ToString("B");
24
25
private bool sectionIdOnRows;
26
- //private WixActionRowCollection standardActions;
27
- //private Output activeOutput;
28
- //private TableDefinitionCollection tableDefinitions;
26
27
/// <summary>
28
/// Creates a linker.
@@ -34,9 +31,6 @@ namespace WixToolset.Core
31
{
32
this.sectionIdOnRows = true; // TODO: what is the correct value for this?
33
37
- //this.standardActions = WindowsInstallerStandard.GetStandardActions();
38
- //this.tableDefinitions = new TableDefinitionCollection(WindowsInstallerStandard.GetTableDefinitions());
39
-
34
//this.extensionData = new List<IExtensionData>();
35
//this.inspectorExtensions = new List<InspectorExtension>();
36
}
@@ -108,11 +102,6 @@ namespace WixToolset.Core
102
103
//this.activeOutput = null;
104
111
-#if MOVE_TO_BACKEND
112
- var actionRows = new List<IntermediateTuple>();
113
- var suppressActionRows = new List<IntermediateTuple>();
114
-#endif
115
-
105
//TableDefinitionCollection customTableDefinitions = new TableDefinitionCollection();
106
//IntermediateTuple customRows = new List<IntermediateTuple>();
107
@@ -232,7 +221,7 @@ namespace WixToolset.Core
221
}
222
223
// Report duplicates that would ultimately end up being primary key collisions.
235
- ReportConflictingSymbolsCommand reportDupes = new ReportConflictingSymbolsCommand(find.PossiblyConflictingSymbols, resolve.ResolvedSections);
224
+ var reportDupes = new ReportConflictingSymbolsCommand(find.PossiblyConflictingSymbols, resolve.ResolvedSections);
225
reportDupes.Execute();
226
227
if (Messaging.Instance.EncounteredError)
@@ -394,19 +383,6 @@ namespace WixToolset.Core
383
}
384
break;
385
397
-#if MOVE_TO_BACKEND
398
- case TupleDefinitionType.WixAction:
399
- //if (this.sectionIdOnRows)
400
- //{
401
- // foreach (Row row in table.Rows)
402
- // {
403
- // row.SectionId = sectionId;
404
- // }
405
- //}
406
- actionRows.Add(tuple);
407
- break;
408
-#endif
409
-
386
#if SOLVE_CUSTOM_TABLE
387
case "WixCustomTable":
388
this.LinkCustomTable(table, customTableDefinitions);
@@ -455,12 +431,6 @@ namespace WixToolset.Core
431
}
432
break;
433
458
-#if MOVE_TO_BACKEND
459
- case TupleDefinitionType.WixSuppressAction:
460
- suppressActionRows.Add(tuple);
461
- break;
462
-#endif
463
-
434
case TupleDefinitionType.WixComplexReference:
435
copyTuple = false;
436
break;
@@ -538,11 +508,6 @@ namespace WixToolset.Core
508
}
509
#endif
510
541
-#if MOVE_TO_BACKEND
542
- // sequence all the actions
543
- this.SequenceActions(actionRows, suppressActionRows);
544
-#endif
545
-
511
#if MOVE_TO_BACKEND
512
// check for missing table and add them or display an error as appropriate
513
switch (this.activeOutput.Type)
@@ -1140,6 +1105,7 @@ namespace WixToolset.Core
1105
}
1106
}
1107
#endif
1108
+
1109
/// <summary>
1110
/// Sends a message to the message delegate if there is one.
1111
/// </summary>
@@ -1726,638 +1692,6 @@ namespace WixToolset.Core
1692
}
1693
#endif
1694
1729
-#if MOVE_TO_BACKEND
1730
- /// <summary>
1731
- /// Set sequence numbers for all the actions and create rows in the output object.
1732
- /// </summary>
1733
- /// <param name="actionRows">Collection of actions to schedule.</param>
1734
- /// <param name="suppressActionRows">Collection of actions to suppress.</param>
1735
- private void SequenceActions(List<IntermediateTuple> actionRows, List<IntermediateTuple> suppressActionRows)
1736
- {
1737
- var overridableActionRows = new WixActionRowCollection();
1738
- var requiredActionRows = new WixActionRowCollection();
1739
- ArrayList scheduledActionRows = new ArrayList();
1740
-
1741
- // gather the required actions for the output type
1742
- if (OutputType.Product == this.activeOutput.Type)
1743
- {
1744
- // AdminExecuteSequence table
1745
- overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "CostFinalize"]);
1746
- overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "CostInitialize"]);
1747
- overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "FileCost"]);
1748
- overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "InstallAdminPackage"]);
1749
- overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "InstallFiles"]);
1750
- overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "InstallFinalize"]);
1751
- overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "InstallInitialize"]);
1752
- overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "InstallValidate"]);
1753
-
1754
- // AdminUISequence table
1755
- overridableActionRows.Add(this.standardActions[SequenceTable.AdminUISequence, "CostFinalize"]);
1756
- overridableActionRows.Add(this.standardActions[SequenceTable.AdminUISequence, "CostInitialize"]);
1757
- overridableActionRows.Add(this.standardActions[SequenceTable.AdminUISequence, "ExecuteAction"]);
1758
- overridableActionRows.Add(this.standardActions[SequenceTable.AdminUISequence, "FileCost"]);
1759
-
1760
- // AdvtExecuteSequence table
1761
- overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "CostFinalize"]);
1762
- overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "CostInitialize"]);
1763
- overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "InstallFinalize"]);
1764
- overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "InstallInitialize"]);
1765
- overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "InstallValidate"]);
1766
- overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "PublishFeatures"]);
1767
- overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "PublishProduct"]);
1768
-
1769
- // InstallExecuteSequence table
1770
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "CostFinalize"]);
1771
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "CostInitialize"]);
1772
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "FileCost"]);
1773
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "InstallFinalize"]);
1774
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "InstallInitialize"]);
1775
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "InstallValidate"]);
1776
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "ProcessComponents"]);
1777
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "PublishFeatures"]);
1778
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "PublishProduct"]);
1779
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterProduct"]);
1780
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterUser"]);
1781
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnpublishFeatures"]);
1782
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "ValidateProductID"]);
1783
-
1784
- // InstallUISequence table
1785
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "CostFinalize"]);
1786
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "CostInitialize"]);
1787
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "ExecuteAction"]);
1788
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "FileCost"]);
1789
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "ValidateProductID"]);
1790
- }
1791
-
1792
- // gather the required actions for each table
1793
- foreach (Table table in this.activeOutput.Tables)
1794
- {
1795
- switch (table.Name)
1796
- {
1797
- case "AppSearch":
1798
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "AppSearch"], true);
1799
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "AppSearch"], true);
1800
- break;
1801
- case "BindImage":
1802
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "BindImage"], true);
1803
- break;
1804
- case "CCPSearch":
1805
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "AppSearch"], true);
1806
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "CCPSearch"], true);
1807
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RMCCPSearch"], true);
1808
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "AppSearch"], true);
1809
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "CCPSearch"], true);
1810
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "RMCCPSearch"], true);
1811
- break;
1812
- case "Class":
1813
- overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "RegisterClassInfo"], true);
1814
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterClassInfo"], true);
1815
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnregisterClassInfo"], true);
1816
- break;
1817
- case "Complus":
1818
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterComPlus"], true);
1819
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnregisterComPlus"], true);
1820
- break;
1821
- case "CreateFolder":
1822
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "CreateFolders"], true);
1823
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveFolders"], true);
1824
- break;
1825
- case "DuplicateFile":
1826
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "DuplicateFiles"], true);
1827
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveDuplicateFiles"], true);
1828
- break;
1829
- case "Environment":
1830
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "WriteEnvironmentStrings"], true);
1831
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveEnvironmentStrings"], true);
1832
- break;
1833
- case "Extension":
1834
- overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "RegisterExtensionInfo"], true);
1835
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterExtensionInfo"], true);
1836
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnregisterExtensionInfo"], true);
1837
- break;
1838
- case "File":
1839
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "InstallFiles"], true);
1840
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveFiles"], true);
1841
- break;
1842
- case "Font":
1843
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterFonts"], true);
1844
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnregisterFonts"], true);
1845
- break;
1846
- case "IniFile":
1847
- case "RemoveIniFile":
1848
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "WriteIniValues"], true);
1849
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveIniValues"], true);
1850
- break;
1851
- case "IsolatedComponent":
1852
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "IsolateComponents"], true);
1853
- break;
1854
- case "LaunchCondition":
1855
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "LaunchConditions"], true);
1856
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "LaunchConditions"], true);
1857
- break;
1858
- case "MIME":
1859
- overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "RegisterMIMEInfo"], true);
1860
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterMIMEInfo"], true);
1861
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnregisterMIMEInfo"], true);
1862
- break;
1863
- case "MoveFile":
1864
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "MoveFiles"], true);
1865
- break;
1866
- case "MsiAssembly":
1867
- overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "MsiPublishAssemblies"], true);
1868
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "MsiPublishAssemblies"], true);
1869
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "MsiUnpublishAssemblies"], true);
1870
- break;
1871
- case "MsiServiceConfig":
1872
- case "MsiServiceConfigFailureActions":
1873
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "MsiConfigureServices"], true);
1874
- break;
1875
- case "ODBCDataSource":
1876
- case "ODBCTranslator":
1877
- case "ODBCDriver":
1878
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "SetODBCFolders"], true);
1879
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "InstallODBC"], true);
1880
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveODBC"], true);
1881
- break;
1882
- case "ProgId":
1883
- overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "RegisterProgIdInfo"], true);
1884
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterProgIdInfo"], true);
1885
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnregisterProgIdInfo"], true);
1886
- break;
1887
- case "PublishComponent":
1888
- overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "PublishComponents"], true);
1889
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "PublishComponents"], true);
1890
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnpublishComponents"], true);
1891
- break;
1892
- case "Registry":
1893
- case "RemoveRegistry":
1894
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "WriteRegistryValues"], true);
1895
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveRegistryValues"], true);
1896
- break;
1897
- case "RemoveFile":
1898
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveFiles"], true);
1899
- break;
1900
- case "SelfReg":
1901
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "SelfRegModules"], true);
1902
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "SelfUnregModules"], true);
1903
- break;
1904
- case "ServiceControl":
1905
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "StartServices"], true);
1906
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "StopServices"], true);
1907
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "DeleteServices"], true);
1908
- break;
1909
- case "ServiceInstall":
1910
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "InstallServices"], true);
1911
- break;
1912
- case "Shortcut":
1913
- overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "CreateShortcuts"], true);
1914
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "CreateShortcuts"], true);
1915
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveShortcuts"], true);
1916
- break;
1917
- case "TypeLib":
1918
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterTypeLibraries"], true);
1919
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnregisterTypeLibraries"], true);
1920
- break;
1921
- case "Upgrade":
1922
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "FindRelatedProducts"], true);
1923
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "FindRelatedProducts"], true);
1924
- // Only add the MigrateFeatureStates action if MigrateFeature attribute is set to yes on at least one UpgradeVersion element.
1925
- foreach (Row row in table.Rows)
1926
- {
1927
- int options = (int)row[4];
1928
- if (MsiInterop.MsidbUpgradeAttributesMigrateFeatures == (options & MsiInterop.MsidbUpgradeAttributesMigrateFeatures))
1929
- {
1930
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "MigrateFeatureStates"], true);
1931
- overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "MigrateFeatureStates"], true);
1932
- break;
1933
- }
1934
- }
1935
- break;
1936
- }
1937
- }
1938
-
1939
- // index all the action rows (look for collisions)
1940
- foreach (WixActionRow actionRow in actionRows)
1941
- {
1942
- if (actionRow.Overridable) // overridable action
1943
- {
1944
- WixActionRow collidingActionRow = overridableActionRows[actionRow.SequenceTable, actionRow.Action];
1945
-
1946
- if (null != collidingActionRow)
1947
- {
1948
- this.OnMessage(WixErrors.OverridableActionCollision(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
1949
- if (null != collidingActionRow.SourceLineNumbers)
1950
- {
1951
- this.OnMessage(WixErrors.OverridableActionCollision2(collidingActionRow.SourceLineNumbers));
1952
- }
1953
- }
1954
- else
1955
- {
1956
- overridableActionRows.Add(actionRow);
1957
- }
1958
- }
1959
- else // unscheduled/scheduled action
1960
- {
1961
- // unscheduled action (allowed for certain standard actions)
1962
- if (null == actionRow.Before && null == actionRow.After && 0 == actionRow.Sequence)
1963
- {
1964
- WixActionRow standardAction = this.standardActions[actionRow.SequenceTable, actionRow.Action];
1965
-
1966
- if (null != standardAction)
1967
- {
1968
- // populate the sequence from the standard action
1969
- actionRow.Sequence = standardAction.Sequence;
1970
- }
1971
- else // not a supported unscheduled action
1972
- {
1973
- throw new InvalidOperationException(WixStrings.EXP_FoundActionRowWithNoSequenceBeforeOrAfterColumnSet);
1974
- }
1975
- }
1976
-
1977
- WixActionRow collidingActionRow = requiredActionRows[actionRow.SequenceTable, actionRow.Action];
1978
-
1979
- if (null != collidingActionRow)
1980
- {
1981
- this.OnMessage(WixErrors.ActionCollision(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
1982
- if (null != collidingActionRow.SourceLineNumbers)
1983
- {
1984
- this.OnMessage(WixErrors.ActionCollision2(collidingActionRow.SourceLineNumbers));
1985
- }
1986
- }
1987
- else
1988
- {
1989
- requiredActionRows.Add(actionRow.Clone());
1990
- }
1991
- }
1992
- }
1993
-
1994
- // add the overridable action rows that are not overridden to the required action rows
1995
- foreach (WixActionRow actionRow in overridableActionRows)
1996
- {
1997
- if (null == requiredActionRows[actionRow.SequenceTable, actionRow.Action])
1998
- {
1999
- requiredActionRows.Add(actionRow.Clone());
2000
- }
2001
- }
2002
-
2003
- // suppress the required actions that are overridable
2004
- foreach (Row suppressActionRow in suppressActionRows)
2005
- {
2006
- SequenceTable sequenceTable = (SequenceTable)Enum.Parse(typeof(SequenceTable), (string)suppressActionRow[0]);
2007
- string action = (string)suppressActionRow[1];
2008
-
2009
- // get the action being suppressed (if it exists)
2010
- WixActionRow requiredActionRow = requiredActionRows[sequenceTable, action];
2011
-
2012
- // if there is an overridable row to suppress; suppress it
2013
- // there is no warning if there is no action to suppress because the action may be suppressed from a merge module in the binder
2014
- if (null != requiredActionRow)
2015
- {
2016
- if (requiredActionRow.Overridable)
2017
- {
2018
- this.OnMessage(WixWarnings.SuppressAction(suppressActionRow.SourceLineNumbers, action, sequenceTable.ToString()));
2019
- if (null != requiredActionRow.SourceLineNumbers)
2020
- {
2021
- this.OnMessage(WixWarnings.SuppressAction2(requiredActionRow.SourceLineNumbers));
2022
- }
2023
- requiredActionRows.Remove(sequenceTable, action);
2024
- }
2025
- else // suppressing a non-overridable action row
2026
- {
2027
- this.OnMessage(WixErrors.SuppressNonoverridableAction(suppressActionRow.SourceLineNumbers, sequenceTable.ToString(), action));
2028
- if (null != requiredActionRow.SourceLineNumbers)
2029
- {
2030
- this.OnMessage(WixErrors.SuppressNonoverridableAction2(requiredActionRow.SourceLineNumbers));
2031
- }
2032
- }
2033
- }
2034
- }
2035
-
2036
- // create a copy of the required action rows so that new rows can be added while enumerating
2037
- WixActionRow[] copyOfRequiredActionRows = new WixActionRow[requiredActionRows.Count];
2038
- requiredActionRows.CopyTo(copyOfRequiredActionRows, 0);
2039
-
2040
- // build up dependency trees of the relatively scheduled actions
2041
- foreach (WixActionRow actionRow in copyOfRequiredActionRows)
2042
- {
2043
- if (0 == actionRow.Sequence)
2044
- {
2045
- // check for standard actions that don't have a sequence number in a merge module
2046
- if (OutputType.Module == this.activeOutput.Type && WindowsInstallerStandard.IsStandardAction(actionRow.Action))
2047
- {
2048
- this.OnMessage(WixErrors.StandardActionRelativelyScheduledInModule(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
2049
- }
2050
-
2051
- this.SequenceActionRow(actionRow, requiredActionRows);
2052
- }
2053
- else if (OutputType.Module == this.activeOutput.Type && 0 < actionRow.Sequence && !WindowsInstallerStandard.IsStandardAction(actionRow.Action)) // check for custom actions and dialogs that have a sequence number
2054
- {
2055
- this.OnMessage(WixErrors.CustomActionSequencedInModule(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
2056
- }
2057
- }
2058
-
2059
- // look for standard actions with sequence restrictions that aren't necessarily scheduled based on the presence of a particular table
2060
- if (requiredActionRows.Contains(SequenceTable.InstallExecuteSequence, "DuplicateFiles") && !requiredActionRows.Contains(SequenceTable.InstallExecuteSequence, "InstallFiles"))
2061
- {
2062
- requiredActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "InstallFiles"], true);
2063
- }
2064
-
2065
- // schedule actions
2066
- if (OutputType.Module == this.activeOutput.Type)
2067
- {
2068
- // add the action row to the list of scheduled action rows
2069
- scheduledActionRows.AddRange(requiredActionRows);
2070
- }
2071
- else
2072
- {
2073
- // process each sequence table individually
2074
- foreach (SequenceTable sequenceTable in Enum.GetValues(typeof(SequenceTable)))
2075
- {
2076
- // create a collection of just the action rows in this sequence
2077
- WixActionRowCollection sequenceActionRows = new WixActionRowCollection();
2078
- foreach (WixActionRow actionRow in requiredActionRows)
2079
- {
2080
- if (sequenceTable == actionRow.SequenceTable)
2081
- {
2082
- sequenceActionRows.Add(actionRow);
2083
- }
2084
- }
2085
-
2086
- // schedule the absolutely scheduled actions (by sorting them by their sequence numbers)
2087
- ArrayList absoluteActionRows = new ArrayList();
2088
- foreach (WixActionRow actionRow in sequenceActionRows)
2089
- {
2090
- if (0 != actionRow.Sequence)
2091
- {
2092
- // look for sequence number collisions
2093
- foreach (WixActionRow sequenceScheduledActionRow in absoluteActionRows)
2094
- {
2095
- if (sequenceScheduledActionRow.Sequence == actionRow.Sequence)
2096
- {
2097
- this.OnMessage(WixWarnings.ActionSequenceCollision(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, sequenceScheduledActionRow.Action, actionRow.Sequence));
2098
- if (null != sequenceScheduledActionRow.SourceLineNumbers)
2099
- {
2100
- this.OnMessage(WixWarnings.ActionSequenceCollision2(sequenceScheduledActionRow.SourceLineNumbers));
2101
- }
2102
- }
2103
- }
2104
-
2105
- absoluteActionRows.Add(actionRow);
2106
- }
2107
- }
2108
- absoluteActionRows.Sort();
2109
-
2110
- // schedule the relatively scheduled actions (by resolving the dependency trees)
2111
- int previousUsedSequence = 0;
2112
- ArrayList relativeActionRows = new ArrayList();
2113
- for (int j = 0; j < absoluteActionRows.Count; j++)
2114
- {
2115
- WixActionRow absoluteActionRow = (WixActionRow)absoluteActionRows[j];
2116
- int unusedSequence;
2117
-
2118
- // get all the relatively scheduled action rows occuring before this absolutely scheduled action row
2119
- RowIndexedList<WixActionRow> allPreviousActionRows = new RowIndexedList<WixActionRow>();
2120
- absoluteActionRow.GetAllPreviousActionRows(sequenceTable, allPreviousActionRows);
2121
-
2122
- // get all the relatively scheduled action rows occuring after this absolutely scheduled action row
2123
- RowIndexedList<WixActionRow> allNextActionRows = new RowIndexedList<WixActionRow>();
2124
- absoluteActionRow.GetAllNextActionRows(sequenceTable, allNextActionRows);
2125
-
2126
- // check for relatively scheduled actions occuring before/after a special action (these have a negative sequence number)
2127
- if (0 > absoluteActionRow.Sequence && (0 < allPreviousActionRows.Count || 0 < allNextActionRows.Count))
2128
- {
2129
- // create errors for all the before actions
2130
- foreach (WixActionRow actionRow in allPreviousActionRows)
2131
- {
2132
- this.OnMessage(WixErrors.ActionScheduledRelativeToTerminationAction(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, absoluteActionRow.Action));
2133
- }
2134
-
2135
- // create errors for all the after actions
2136
- foreach (WixActionRow actionRow in allNextActionRows)
2137
- {
2138
- this.OnMessage(WixErrors.ActionScheduledRelativeToTerminationAction(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, absoluteActionRow.Action));
2139
- }
2140
-
2141
- // if there is source line information for the absolutely scheduled action display it
2142
- if (null != absoluteActionRow.SourceLineNumbers)
2143
- {
2144
- this.OnMessage(WixErrors.ActionScheduledRelativeToTerminationAction2(absoluteActionRow.SourceLineNumbers));
2145
- }
2146
-
2147
- continue;
2148
- }
2149
-
2150
- // schedule the action rows before this one
2151
- unusedSequence = absoluteActionRow.Sequence - 1;
2152
- for (int i = allPreviousActionRows.Count - 1; i >= 0; i--)
2153
- {
2154
- WixActionRow relativeActionRow = (WixActionRow)allPreviousActionRows[i];
2155
-
2156
- // look for collisions
2157
- if (unusedSequence == previousUsedSequence)
2158
- {
2159
- this.OnMessage(WixErrors.NoUniqueActionSequenceNumber(relativeActionRow.SourceLineNumbers, relativeActionRow.SequenceTable.ToString(), relativeActionRow.Action, absoluteActionRow.Action));
2160
- if (null != absoluteActionRow.SourceLineNumbers)
2161
- {
2162
- this.OnMessage(WixErrors.NoUniqueActionSequenceNumber2(absoluteActionRow.SourceLineNumbers));
2163
- }
2164
-
2165
- unusedSequence++;
2166
- }
2167
-
2168
- relativeActionRow.Sequence = unusedSequence;
2169
- relativeActionRows.Add(relativeActionRow);
2170
-
2171
- unusedSequence--;
2172
- }
2173
-
2174
- // determine the next used action sequence number
2175
- int nextUsedSequence;
2176
- if (absoluteActionRows.Count > j + 1)
2177
- {
2178
- nextUsedSequence = ((WixActionRow)absoluteActionRows[j + 1]).Sequence;
2179
- }
2180
- else
2181
- {
2182
- nextUsedSequence = short.MaxValue + 1;
2183
- }
2184
-
2185
- // schedule the action rows after this one
2186
- unusedSequence = absoluteActionRow.Sequence + 1;
2187
- for (int i = 0; i < allNextActionRows.Count; i++)
2188
- {
2189
- WixActionRow relativeActionRow = (WixActionRow)allNextActionRows[i];
2190
-
2191
- if (unusedSequence == nextUsedSequence)
2192
- {
2193
- this.OnMessage(WixErrors.NoUniqueActionSequenceNumber(relativeActionRow.SourceLineNumbers, relativeActionRow.SequenceTable.ToString(), relativeActionRow.Action, absoluteActionRow.Action));
2194
- if (null != absoluteActionRow.SourceLineNumbers)
2195
- {
2196
- this.OnMessage(WixErrors.NoUniqueActionSequenceNumber2(absoluteActionRow.SourceLineNumbers));
2197
- }
2198
-
2199
- unusedSequence--;
2200
- }
2201
-
2202
- relativeActionRow.Sequence = unusedSequence;
2203
- relativeActionRows.Add(relativeActionRow);
2204
-
2205
- unusedSequence++;
2206
- }
2207
-
2208
- // keep track of this sequence number as the previous used sequence number for the next iteration
2209
- previousUsedSequence = absoluteActionRow.Sequence;
2210
- }
2211
-
2212
- // add the absolutely and relatively scheduled actions to the list of scheduled actions
2213
- scheduledActionRows.AddRange(absoluteActionRows);
2214
- scheduledActionRows.AddRange(relativeActionRows);
2215
- }
2216
- }
2217
-
2218
- // create the action rows for sequences that are not suppressed
2219
- foreach (WixActionRow actionRow in scheduledActionRows)
2220
- {
2221
- // get the table definition for the action (and ensure the proper table exists for a module)
2222
- TableDefinition sequenceTableDefinition = null;
2223
- switch (actionRow.SequenceTable)
2224
- {
2225
- case SequenceTable.AdminExecuteSequence:
2226
- if (OutputType.Module == this.activeOutput.Type)
2227
- {
2228
- this.activeOutput.EnsureTable(this.tableDefinitions["AdminExecuteSequence"]);
2229
- sequenceTableDefinition = this.tableDefinitions["ModuleAdminExecuteSequence"];
2230
- }
2231
- else
2232
- {
2233
- sequenceTableDefinition = this.tableDefinitions["AdminExecuteSequence"];
2234
- }
2235
- break;
2236
- case SequenceTable.AdminUISequence:
2237
- if (OutputType.Module == this.activeOutput.Type)
2238
- {
2239
- this.activeOutput.EnsureTable(this.tableDefinitions["AdminUISequence"]);
2240
- sequenceTableDefinition = this.tableDefinitions["ModuleAdminUISequence"];
2241
- }
2242
- else
2243
- {
2244
- sequenceTableDefinition = this.tableDefinitions["AdminUISequence"];
2245
- }
2246
- break;
2247
- case SequenceTable.AdvtExecuteSequence:
2248
- if (OutputType.Module == this.activeOutput.Type)
2249
- {
2250
- this.activeOutput.EnsureTable(this.tableDefinitions["AdvtExecuteSequence"]);
2251
- sequenceTableDefinition = this.tableDefinitions["ModuleAdvtExecuteSequence"];
2252
- }
2253
- else
2254
- {
2255
- sequenceTableDefinition = this.tableDefinitions["AdvtExecuteSequence"];
2256
- }
2257
- break;
2258
- case SequenceTable.InstallExecuteSequence:
2259
- if (OutputType.Module == this.activeOutput.Type)
2260
- {
2261
- this.activeOutput.EnsureTable(this.tableDefinitions["InstallExecuteSequence"]);
2262
- sequenceTableDefinition = this.tableDefinitions["ModuleInstallExecuteSequence"];
2263
- }
2264
- else
2265
- {
2266
- sequenceTableDefinition = this.tableDefinitions["InstallExecuteSequence"];
2267
- }
2268
- break;
2269
- case SequenceTable.InstallUISequence:
2270
- if (OutputType.Module == this.activeOutput.Type)
2271
- {
2272
- this.activeOutput.EnsureTable(this.tableDefinitions["InstallUISequence"]);
2273
- sequenceTableDefinition = this.tableDefinitions["ModuleInstallUISequence"];
2274
- }
2275
- else
2276
- {
2277
- sequenceTableDefinition = this.tableDefinitions["InstallUISequence"];
2278
- }
2279
- break;
2280
- }
2281
-
2282
- // create the action sequence row in the output
2283
- Table sequenceTable = this.activeOutput.EnsureTable(sequenceTableDefinition);
2284
- Row row = sequenceTable.CreateRow(actionRow.SourceLineNumbers);
2285
- if (this.sectionIdOnRows)
2286
- {
2287
- row.SectionId = actionRow.SectionId;
2288
- }
2289
-
2290
- if (OutputType.Module == this.activeOutput.Type)
2291
- {
2292
- row[0] = actionRow.Action;
2293
- if (0 != actionRow.Sequence)
2294
- {
2295
- row[1] = actionRow.Sequence;
2296
- }
2297
- else
2298
- {
2299
- bool after = (null == actionRow.Before);
2300
- row[2] = after ? actionRow.After : actionRow.Before;
2301
- row[3] = after ? 1 : 0;
2302
- }
2303
- row[4] = actionRow.Condition;
2304
- }
2305
- else
2306
- {
2307
- row[0] = actionRow.Action;
2308
- row[1] = actionRow.Condition;
2309
- row[2] = actionRow.Sequence;
2310
- }
2311
- }
2312
- }
2313
-
2314
- /// <summary>
2315
- /// Sequence an action before or after a standard action.
2316
- /// </summary>
2317
- /// <param name="actionRow">The action row to be sequenced.</param>
2318
- /// <param name="requiredActionRows">Collection of actions which must be included.</param>
2319
- [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.InvalidOperationException.#ctor(System.String)")]
2320
- private void SequenceActionRow(WixActionRow actionRow, WixActionRowCollection requiredActionRows)
2321
- {
2322
- bool after = false;
2323
- if (actionRow.After != null)
2324
- {
2325
- after = true;
2326
- }
2327
- else if (actionRow.Before == null)
2328
- {
2329
- throw new InvalidOperationException(WixStrings.EXP_FoundActionRowWithNoSequenceBeforeOrAfterColumnSet);
2330
- }
2331
-
2332
- string parentActionName = (after ? actionRow.After : actionRow.Before);
2333
- WixActionRow parentActionRow = requiredActionRows[actionRow.SequenceTable, parentActionName];
2334
-
2335
- if (null == parentActionRow)
2336
- {
2337
- parentActionRow = this.standardActions[actionRow.SequenceTable, parentActionName];
2338
-
2339
- // if the missing parent action is a standard action (with a suggested sequence number), add it
2340
- if (null != parentActionRow)
2341
- {
2342
- // Create a clone to avoid modifying the static copy of the object.
2343
- parentActionRow = parentActionRow.Clone();
2344
- requiredActionRows.Add(parentActionRow);
2345
- }
2346
- else
2347
- {
2348
- throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_FoundActionRowWinNonExistentAction, (after ? "After" : "Before"), parentActionName));
2349
- }
2350
- }
2351
- else if (actionRow == parentActionRow || actionRow.ContainsChildActionRow(parentActionRow)) // cycle detected
2352
- {
2353
- throw new WixException(WixErrors.ActionCircularDependency(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, parentActionRow.Action));
2354
- }
2355
-
2356
- // Add this action to the appropriate list of dependent action rows.
2357
- WixActionRowCollection relatedRows = (after ? parentActionRow.NextActionRows : parentActionRow.PreviousActionRows);
2358
- relatedRows.Add(actionRow);
2359
- }
2360
-#endif
1695
1696
/// <summary>
1697
/// Resolve features for columns that have null guid placeholders.
src/WixToolset.Core/WindowsInstallerStandard.cs
deleted
-260
@@ -1,260 +0,0 @@
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
4
-{
5
- using System.Collections.Generic;
6
- using WixToolset.Data;
7
- using WixToolset.Data.Tuples;
8
-
9
- internal class WindowsInstallerStandard
10
- {
11
- private static readonly HashSet<string> standardActionNames = new HashSet<string>
12
- {
13
- "AllocateRegistrySpace",
14
- "AppSearch",
15
- "BindImage",
16
- "CCPSearch",
17
- "CostFinalize",
18
- "CostInitialize",
19
- "CreateFolders",
20
- "CreateShortcuts",
21
- "DeleteServices",
22
- "DisableRollback",
23
- "DuplicateFiles",
24
- "ExecuteAction",
25
- "FileCost",
26
- "FindRelatedProducts",
27
- "ForceReboot",
28
- "InstallAdminPackage",
29
- "InstallExecute",
30
- "InstallExecuteAgain",
31
- "InstallFiles",
32
- "InstallFinalize",
33
- "InstallInitialize",
34
- "InstallODBC",
35
- "InstallServices",
36
- "InstallSFPCatalogFile",
37
- "InstallValidate",
38
- "IsolateComponents",
39
- "LaunchConditions",
40
- "MigrateFeatureStates",
41
- "MoveFiles",
42
- "MsiConfigureServices",
43
- "MsiPublishAssemblies",
44
- "MsiUnpublishAssemblies",
45
- "PatchFiles",
46
- "ProcessComponents",
47
- "PublishComponents",
48
- "PublishFeatures",
49
- "PublishProduct",
50
- "RegisterClassInfo",
51
- "RegisterComPlus",
52
- "RegisterExtensionInfo",
53
- "RegisterFonts",
54
- "RegisterMIMEInfo",
55
- "RegisterProduct",
56
- "RegisterProgIdInfo",
57
- "RegisterTypeLibraries",
58
- "RegisterUser",
59
- "RemoveDuplicateFiles",
60
- "RemoveEnvironmentStrings",
61
- "RemoveExistingProducts",
62
- "RemoveFiles",
63
- "RemoveFolders",
64
- "RemoveIniValues",
65
- "RemoveODBC",
66
- "RemoveRegistryValues",
67
- "RemoveShortcuts",
68
- "ResolveSource",
69
- "RMCCPSearch",
70
- "ScheduleReboot",
71
- "SelfRegModules",
72
- "SelfUnregModules",
73
- "SetODBCFolders",
74
- "StartServices",
75
- "StopServices",
76
- "UnpublishComponents",
77
- "UnpublishFeatures",
78
- "UnregisterClassInfo",
79
- "UnregisterComPlus",
80
- "UnregisterExtensionInfo",
81
- "UnregisterFonts",
82
- "UnregisterMIMEInfo",
83
- "UnregisterProgIdInfo",
84
- "UnregisterTypeLibraries",
85
- "ValidateProductID",
86
- "WriteEnvironmentStrings",
87
- "WriteIniValues",
88
- "WriteRegistryValues",
89
- };
90
-
91
- private static readonly WixActionTuple[] standardActions = new[]
92
- {
93
- new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallInitialize", AccessModifier.Public)) { Action="InstallInitialize", Sequence=1500, SequenceTable=SequenceTable.AdminExecuteSequence },
94
- new WixActionTuple(null, new Identifier("AdvtExecuteSequence/InstallInitialize", AccessModifier.Public)) { Action="InstallInitialize", Sequence=1500, SequenceTable=SequenceTable.AdvtExecuteSequence },
95
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallInitialize", AccessModifier.Public)) { Action="InstallInitialize", Sequence=1500, SequenceTable=SequenceTable.InstallExecuteSequence },
96
-
97
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallExecute", AccessModifier.Public)) { Action="InstallExecute", Sequence=6500, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="NOT Installed" },
98
-
99
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallExecuteAgain", AccessModifier.Public)) { Action="InstallExecuteAgain", Sequence=6550, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="NOT Installed" },
100
-
101
- new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallFinalize", AccessModifier.Public)) { Action="InstallFinalize", Sequence=6600, SequenceTable=SequenceTable.AdminExecuteSequence },
102
- new WixActionTuple(null, new Identifier("AdvtExecuteSequence/InstallFinalize", AccessModifier.Public)) { Action="InstallFinalize", Sequence=6600, SequenceTable=SequenceTable.AdvtExecuteSequence },
103
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallFinalize", AccessModifier.Public)) { Action="InstallFinalize", Sequence=6600, SequenceTable=SequenceTable.InstallExecuteSequence },
104
-
105
- new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallFiles", AccessModifier.Public)) { Action="InstallFiles", Sequence=4000, SequenceTable=SequenceTable.AdminExecuteSequence },
106
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallFiles", AccessModifier.Public)) { Action="InstallFiles", Sequence=4000, SequenceTable=SequenceTable.InstallExecuteSequence },
107
-
108
- new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallAdminPackage", AccessModifier.Public)) { Action="InstallAdminPackage", Sequence=3900, SequenceTable=SequenceTable.AdminExecuteSequence },
109
-
110
- new WixActionTuple(null, new Identifier("AdminExecuteSequence/FileCost", AccessModifier.Public)) { Action="FileCost", Sequence=900, SequenceTable=SequenceTable.AdminExecuteSequence },
111
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/FileCost", AccessModifier.Public)) { Action="FileCost", Sequence=900, SequenceTable=SequenceTable.InstallExecuteSequence },
112
- new WixActionTuple(null, new Identifier("InstallUISequence/FileCost", AccessModifier.Public)) { Action="FileCost", Sequence=900, SequenceTable=SequenceTable.InstallUISequence },
113
-
114
- new WixActionTuple(null, new Identifier("AdminExecuteSequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.AdminExecuteSequence },
115
- new WixActionTuple(null, new Identifier("AdminUISequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.AdminUISequence },
116
- new WixActionTuple(null, new Identifier("AdvtExecuteSequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.AdvtExecuteSequence },
117
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.InstallExecuteSequence },
118
- new WixActionTuple(null, new Identifier("InstallUISequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.InstallUISequence },
119
-
120
- new WixActionTuple(null, new Identifier("AdminExecuteSequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.AdminExecuteSequence },
121
- new WixActionTuple(null, new Identifier("AdminUISequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.AdminUISequence },
122
- new WixActionTuple(null, new Identifier("AdvtExecuteSequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.AdvtExecuteSequence },
123
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.InstallExecuteSequence },
124
- new WixActionTuple(null, new Identifier("InstallUISequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.InstallUISequence },
125
-
126
- new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallValidate", AccessModifier.Public)) { Action="InstallValidate", Sequence=1400, SequenceTable=SequenceTable.AdminExecuteSequence },
127
- new WixActionTuple(null, new Identifier("AdvtExecuteSequence/InstallValidate", AccessModifier.Public)) { Action="InstallValidate", Sequence=1400, SequenceTable=SequenceTable.AdvtExecuteSequence },
128
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallValidate", AccessModifier.Public)) { Action="InstallValidate", Sequence=1400, SequenceTable=SequenceTable.InstallExecuteSequence },
129
-
130
- new WixActionTuple(null, new Identifier("AdminUISequence/ExecuteAction", AccessModifier.Public)) { Action="ExecuteAction", Sequence=1300, SequenceTable=SequenceTable.AdminUISequence },
131
- new WixActionTuple(null, new Identifier("InstallUISequence/ExecuteAction", AccessModifier.Public)) { Action="ExecuteAction", Sequence=1300, SequenceTable=SequenceTable.InstallUISequence },
132
-
133
- new WixActionTuple(null, new Identifier("AdvtExecuteSequence/CreateShortcuts", AccessModifier.Public)) { Action="CreateShortcuts", Sequence=4500, SequenceTable=SequenceTable.AdvtExecuteSequence },
134
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/CreateShortcuts", AccessModifier.Public)) { Action="CreateShortcuts", Sequence=4500, SequenceTable=SequenceTable.InstallExecuteSequence },
135
-
136
- new WixActionTuple(null, new Identifier("AdvtExecuteSequence/MsiPublishAssemblies", AccessModifier.Public)) { Action="MsiPublishAssemblies", Sequence=6250, SequenceTable=SequenceTable.AdvtExecuteSequence },
137
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/MsiPublishAssemblies", AccessModifier.Public)) { Action="MsiPublishAssemblies", Sequence=6250, SequenceTable=SequenceTable.InstallExecuteSequence },
138
-
139
- //<action name="PublishComponents" sequence="6200" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
140
- //<action name="PublishFeatures" sequence="6300" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
141
- //<action name="PublishProduct" sequence="6400" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
142
- //<action name="RegisterClassInfo" sequence="4600" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
143
- //<action name="RegisterExtensionInfo" sequence="4700" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
144
- //<action name="RegisterMIMEInfo" sequence="4900" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
145
- //<action name="RegisterProgIdInfo" sequence="4800" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
146
- //<action name="AllocateRegistrySpace" condition="NOT Installed" sequence="1550" InstallExecuteSequence="yes" />
147
- //<action name="AppSearch" sequence="50" InstallExecuteSequence="yes" InstallUISequence="yes" />
148
- //<action name="BindImage" sequence="4300" InstallExecuteSequence="yes" />
149
- //<action name="CreateFolders" sequence="3700" InstallExecuteSequence="yes" />
150
- //<action name="DuplicateFiles" sequence="4210" InstallExecuteSequence="yes" />
151
- //<action name="FindRelatedProducts" sequence="25" InstallExecuteSequence="yes" InstallUISequence="yes" />
152
- //<action name="InstallODBC" sequence="5400" InstallExecuteSequence="yes" />
153
- //<action name="InstallServices" condition="VersionNT" sequence="5800" InstallExecuteSequence="yes" />
154
- //<action name="MsiConfigureServices" condition="VersionNT>=600" sequence="5850" InstallExecuteSequence="yes" />
155
- //<action name="IsolateComponents" sequence="950" InstallExecuteSequence="yes" InstallUISequence="yes" />
156
- //<action name="LaunchConditions" sequence="100" AdminExecuteSequence="yes" AdminUISequence="yes" InstallExecuteSequence="yes" InstallUISequence="yes" />
157
- //<action name="MigrateFeatureStates" sequence="1200" InstallExecuteSequence="yes" InstallUISequence="yes" />
158
- //<action name="MoveFiles" sequence="3800" InstallExecuteSequence="yes" />
159
- //<action name="PatchFiles" sequence="4090" AdminExecuteSequence="yes" InstallExecuteSequence="yes" />
160
- //<action name="ProcessComponents" sequence="1600" InstallExecuteSequence="yes" />
161
- //<action name="RegisterComPlus" sequence="5700" InstallExecuteSequence="yes" />
162
- //<action name="RegisterFonts" sequence="5300" InstallExecuteSequence="yes" />
163
- //<action name="RegisterProduct" sequence="6100" InstallExecuteSequence="yes" />
164
- //<action name="RegisterTypeLibraries" sequence="5500" InstallExecuteSequence="yes" />
165
- //<action name="RegisterUser" sequence="6000" InstallExecuteSequence="yes" />
166
- //<action name="RemoveDuplicateFiles" sequence="3400" InstallExecuteSequence="yes" />
167
- //<action name="RemoveEnvironmentStrings" sequence="3300" InstallExecuteSequence="yes" />
168
- //<action name="RemoveFiles" sequence="3500" InstallExecuteSequence="yes" />
169
- //<action name="RemoveFolders" sequence="3600" InstallExecuteSequence="yes" />
170
- //<action name="RemoveIniValues" sequence="3100" InstallExecuteSequence="yes" />
171
- //<action name="RemoveODBC" sequence="2400" InstallExecuteSequence="yes" />
172
- //<action name="RemoveRegistryValues" sequence="2600" InstallExecuteSequence="yes" />
173
- //<action name="RemoveShortcuts" sequence="3200" InstallExecuteSequence="yes" />
174
- //<action name="SelfRegModules" sequence="5600" InstallExecuteSequence="yes" />
175
- //<action name="SelfUnregModules" sequence="2200" InstallExecuteSequence="yes" />
176
- //<action name="SetODBCFolders" sequence="1100" InstallExecuteSequence="yes" />
177
-
178
-
179
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/CCPSearch", AccessModifier.Public)) { Action="CCPSearch", Sequence=500, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="NOT Installed" },
180
- new WixActionTuple(null, new Identifier("InstallUISequence/CCPSearch", AccessModifier.Public)) { Action="CCPSearch", Sequence=500, SequenceTable=SequenceTable.InstallUISequence, Condition="NOT Installed" },
181
-
182
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/DeleteServices", AccessModifier.Public)) { Action="DeleteServices", Sequence=2000, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="VersionNT" },
183
-
184
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/RMCCPSearch", AccessModifier.Public)) { Action="RMCCPSearch", Sequence=600, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="NOT Installed" },
185
- new WixActionTuple(null, new Identifier("InstallUISequence/RMCCPSearch", AccessModifier.Public)) { Action="RMCCPSearch", Sequence=600, SequenceTable=SequenceTable.InstallUISequence, Condition="NOT Installed" },
186
-
187
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/StartServices", AccessModifier.Public)) { Action="StartServices", Sequence=5900, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="VersionNT" },
188
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/StopServices", AccessModifier.Public)) { Action="StopServices", Sequence=1900, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="VersionNT" },
189
-
190
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/MsiUnpublishAssemblies", AccessModifier.Public)) { Action="MsiUnpublishAssemblies", Sequence=1750, SequenceTable=SequenceTable.InstallExecuteSequence },
191
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnpublishComponents", AccessModifier.Public)) { Action="UnpublishComponents", Sequence=1700, SequenceTable=SequenceTable.InstallExecuteSequence },
192
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnpublishFeatures", AccessModifier.Public)) { Action="UnpublishFeatures", Sequence=1800, SequenceTable=SequenceTable.InstallExecuteSequence },
193
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterClassInfo", AccessModifier.Public)) { Action="UnregisterClassInfo", Sequence=2700, SequenceTable=SequenceTable.InstallExecuteSequence },
194
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterComPlus", AccessModifier.Public)) { Action="UnregisterComPlus", Sequence=2100, SequenceTable=SequenceTable.InstallExecuteSequence },
195
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterExtensionInfo", AccessModifier.Public)) { Action="UnregisterExtensionInfo", Sequence=2800, SequenceTable=SequenceTable.InstallExecuteSequence },
196
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterFonts", AccessModifier.Public)) { Action="UnregisterFonts", Sequence=2500, SequenceTable=SequenceTable.InstallExecuteSequence },
197
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterMIMEInfo", AccessModifier.Public)) { Action="UnregisterMIMEInfo", Sequence=3000, SequenceTable=SequenceTable.InstallExecuteSequence },
198
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterProgIdInfo", AccessModifier.Public)) { Action="UnregisterProgIdInfo", Sequence=2900, SequenceTable=SequenceTable.InstallExecuteSequence },
199
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterTypeLibraries", AccessModifier.Public)) { Action="UnregisterTypeLibraries", Sequence=2300, SequenceTable=SequenceTable.InstallExecuteSequence },
200
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/ValidateProductID", AccessModifier.Public)) { Action="ValidateProductID", Sequence=700, SequenceTable=SequenceTable.InstallExecuteSequence },
201
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/WriteEnvironmentStrings", AccessModifier.Public)) { Action="WriteEnvironmentStrings", Sequence=5200, SequenceTable=SequenceTable.InstallExecuteSequence },
202
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/WriteIniValues", AccessModifier.Public)) { Action="WriteIniValues", Sequence=5100, SequenceTable=SequenceTable.InstallExecuteSequence },
203
- new WixActionTuple(null, new Identifier("InstallExecuteSequence/WriteRegistryValues", AccessModifier.Public)) { Action="WriteRegistryValues", Sequence=5000, SequenceTable=SequenceTable.InstallExecuteSequence },
204
- };
205
-
206
- private static readonly HashSet<string> standardDirectories = new HashSet<string>
207
- {
208
- "TARGETDIR",
209
- "AdminToolsFolder",
210
- "AppDataFolder",
211
- "CommonAppDataFolder",
212
- "CommonFilesFolder",
213
- "DesktopFolder",
214
- "FavoritesFolder",
215
- "FontsFolder",
216
- "LocalAppDataFolder",
217
- "MyPicturesFolder",
218
- "PersonalFolder",
219
- "ProgramFilesFolder",
220
- "ProgramMenuFolder",
221
- "SendToFolder",
222
- "StartMenuFolder",
223
- "StartupFolder",
224
- "System16Folder",
225
- "SystemFolder",
226
- "TempFolder",
227
- "TemplateFolder",
228
- "WindowsFolder",
229
- "CommonFiles64Folder",
230
- "ProgramFiles64Folder",
231
- "System64Folder",
232
- "NetHoodFolder",
233
- "PrintHoodFolder",
234
- "RecentFolder",
235
- "WindowsVolume",
236
- };
237
-
238
- /// <summary>
239
- /// Find out if an action is a standard action.
240
- /// </summary>
241
- /// <param name="actionName">Name of the action.</param>
242
- /// <returns>true if the action is standard, false otherwise.</returns>
243
- public static bool IsStandardAction(string actionName)
244
- {
245
- return standardActionNames.Contains(actionName);
246
- }
247
-
248
- public static WixActionTuple[] StandardActions() => standardActions;
249
-
250
- /// <summary>
251
- /// Find out if a directory is a standard directory.
252
- /// </summary>
253
- /// <param name="directoryName">Name of the directory.</param>
254
- /// <returns>true if the directory is standard, false otherwise.</returns>
255
- public static bool IsStandardDirectory(string directoryName)
256
- {
257
- return standardDirectories.Contains(directoryName);
258
- }
259
- }
260
-}
src/WixToolset.Core/WixStrings.Designer.cs
+2
-2
@@ -163,7 +163,7 @@ namespace WixToolset {
163
/// <summary>
164
/// Looks up a localized string similar to Found an ActionRow with a non-existent {0} action: {1}..
165
/// </summary>
166
- internal static string EXP_FoundActionRowWinNonExistentAction {
166
+ public static string EXP_FoundActionRowWinNonExistentAction {
167
get {
168
return ResourceManager.GetString("EXP_FoundActionRowWinNonExistentAction", resourceCulture);
169
}
@@ -172,7 +172,7 @@ namespace WixToolset {
172
/// <summary>
173
/// Looks up a localized string similar to Found an ActionRow with no Sequence, Before, or After column set..
174
/// </summary>
175
- internal static string EXP_FoundActionRowWithNoSequenceBeforeOrAfterColumnSet {
175
+ public static string EXP_FoundActionRowWithNoSequenceBeforeOrAfterColumnSet {
176
get {
177
return ResourceManager.GetString("EXP_FoundActionRowWithNoSequenceBeforeOrAfterColumnSet", resourceCulture);
178
}
src/WixToolset.Data.WindowsInstaller/Data/tables.xml
+1
-1
@@ -1468,7 +1468,7 @@
1468
<columnDefinition name="PatchGroup" type="number" length="4" />
1469
<columnDefinition name="Attributes" type="number" length="4"/>
1470
<columnDefinition name="PatchAttributes" type="number" length="4" nullable="yes"/>
1471
- <columnDefinition name="DeltaPatchHeaderSource" type="string" length="0"/>
1471
+ <columnDefinition name="DeltaPatchHeaderSource" type="string" length="0" nullable="yes"/>
1472
</tableDefinition>
1473
<tableDefinition name="WixBindUpdatedFiles" unreal="yes">
1474
<columnDefinition name="File_" type="string" length="0" primaryKey="yes" modularize="column" keyTable="File" keyColumn="1" category="identifier" />
src/WixToolset.Data.WindowsInstaller/RowDictionary.cs
+1
-2
@@ -77,8 +77,7 @@ namespace WixToolset.Data
77
/// <returns>Row or null if key is not found.</returns>
78
public T Get(string key)
79
{
80
- T result;
81
- return this.TryGetValue(key, out result) ? result : null;
80
+ return this.TryGetValue(key, out var result) ? result : null;
81
}
82
}
83
}
src/WixToolset.Data.WindowsInstaller/Rows/SymbolPathType.cs
deleted
-17
@@ -1,17 +0,0 @@
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.Data.Rows
4
-{
5
- /// <summary>
6
- /// The types that the WixDeltaPatchSymbolPaths table can hold.
7
- /// </summary>
8
- /// <remarks>The order of these values is important since WixDeltaPatchSymbolPaths are sorted by this type.</remarks>
9
- public enum SymbolPathType
10
- {
11
- File,
12
- Component,
13
- Directory,
14
- Media,
15
- Product
16
- };
17
-}
src/WixToolset.Data.WindowsInstaller/Rows/WixActionRow.cs
+28
-24
@@ -8,27 +8,28 @@ namespace WixToolset.Data.Rows
8
using System.Globalization;
9
using System.Xml;
10
using System.Xml.Schema;
11
+ using WixToolset.Data.Tuples;
12
13
/// <summary>
14
/// The Sequence tables that actions may belong to.
15
/// </summary>
15
- public enum SequenceTable
16
- {
17
- /// <summary>AdminUISequence</summary>
18
- AdminUISequence,
16
+ //public enum SequenceTable
17
+ //{
18
+ // /// <summary>AdminUISequence</summary>
19
+ // AdminUISequence,
20
20
- /// <summary>AdminExecuteSequence</summary>
21
- AdminExecuteSequence,
21
+ // /// <summary>AdminExecuteSequence</summary>
22
+ // AdminExecuteSequence,
23
23
- /// <summary>AdvtExecuteSequence</summary>
24
- AdvtExecuteSequence,
24
+ // /// <summary>AdvtExecuteSequence</summary>
25
+ // AdvtExecuteSequence,
26
26
- /// <summary>InstallUISequence</summary>
27
- InstallUISequence,
27
+ // /// <summary>InstallUISequence</summary>
28
+ // InstallUISequence,
29
29
- /// <summary>InstallExecuteSequence</summary>
30
- InstallExecuteSequence
31
- }
30
+ // /// <summary>InstallExecuteSequence</summary>
31
+ // InstallExecuteSequence
32
+ //}
33
34
/// <summary>
35
/// Specialization of a row for the sequence tables.
@@ -55,15 +56,15 @@ namespace WixToolset.Data.Rows
56
/// <param name="action">The name of the standard action.</param>
57
/// <param name="condition">The condition of the standard action.</param>
58
/// <param name="sequence">The suggested sequence number of the standard action.</param>
58
- private WixActionRow(SequenceTable sequenceTable, string action, string condition, int sequence) :
59
- base(null, WindowsInstallerStandard.GetTableDefinitions()["WixAction"])
60
- {
61
- this.SequenceTable = sequenceTable;
62
- this.Action = action;
63
- this.Condition = condition;
64
- this.Sequence = sequence;
65
- this.Overridable = true; // all standard actions are overridable by default
66
- }
59
+ //private WixActionRow(SequenceTable sequenceTable, string action, string condition, int sequence) :
60
+ // base(null, WindowsInstallerStandard.GetTableDefinitions()["WixAction"])
61
+ //{
62
+ // this.SequenceTable = sequenceTable;
63
+ // this.Action = action;
64
+ // this.Condition = condition;
65
+ // this.Sequence = sequence;
66
+ // this.Overridable = true; // all standard actions are overridable by default
67
+ //}
68
69
/// <summary>
70
/// Instantiates an ActionRow by copying data from another ActionRow.
@@ -296,13 +297,15 @@ namespace WixToolset.Data.Rows
297
WixActionRow[] actionRows = new WixActionRow[sequenceCount];
298
for (int i = 0; i < sequenceCount; i++)
299
{
299
- WixActionRow actionRow = new WixActionRow(sequenceTables[i], id, condition, sequence);
300
- actionRows[i] = actionRow;
300
+ //WixActionRow actionRow = new WixActionRow(sequenceTables[i], id, condition, sequence);
301
+ //actionRows[i] = actionRow;
302
+ throw new NotImplementedException();
303
}
304
305
return actionRows;
306
}
307
308
+#if DEAD_CODE
309
/// <summary>
310
/// Determines whether this ActionRow contains the specified ActionRow as a child in its dependency tree.
311
/// </summary>
@@ -370,5 +373,6 @@ namespace WixToolset.Data.Rows
373
}
374
}
375
}
376
+#endif
377
}
378
}
src/WixToolset.Data.WindowsInstaller/Rows/WixActionRowCollection.cs
+1
@@ -6,6 +6,7 @@ namespace WixToolset.Data.Rows
6
using System.Collections;
7
using System.Diagnostics;
8
using System.Xml;
9
+ using WixToolset.Data.Tuples;
10
11
/// <summary>
12
/// A collection of action rows sorted by their sequence table and action name.
src/WixToolset.Data.WindowsInstaller/Rows/WixDeltaPatchSymbolPathsRow.cs
+2
@@ -2,6 +2,8 @@
2
3
namespace WixToolset.Data.Rows
4
{
5
+ using WixToolset.Data.Tuples;
6
+
7
/// <summary>
8
/// Specialization of a row for the WixDeltaPatchSymbolPaths table.
9
/// </summary>
src/WixToolset.Data.WindowsInstaller/TableDefinitionCollection.cs
+11
@@ -68,6 +68,17 @@ namespace WixToolset.Data
68
}
69
}
70
71
+ /// <summary>
72
+ /// Tries to get a table definition by name.
73
+ /// </summary>
74
+ /// <param name="tableName">Name of table to locate.</param>
75
+ /// <param name="table">Table definition if found.</param>
76
+ /// <returns>True if table definition was found otherwise false.</returns>
77
+ public bool TryGet(string tableName, out TableDefinition table)
78
+ {
79
+ return this.collection.TryGetValue(tableName, out table);
80
+ }
81
+
82
/// <summary>
83
/// Load a table definition collection from an XmlReader.
84
/// </summary>
src/WixToolset.Data.WindowsInstaller/WindowsInstallerStandard.cs
deleted
-442
@@ -1,442 +0,0 @@
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.Data
4
-{
5
- using System.Collections.Generic;
6
- using System.Reflection;
7
- using System.Xml;
8
- using WixToolset.Data.Rows;
9
-
10
- /// <summary>
11
- /// Represents the Windows Installer standard objects.
12
- /// </summary>
13
- public static class WindowsInstallerStandard
14
- {
15
- private static readonly object lockObject = new object();
16
-
17
- private static TableDefinitionCollection tableDefinitions;
18
- private static WixActionRowCollection standardActions;
19
-
20
- private static HashSet<string> standardActionNames;
21
- private static HashSet<string> standardDirectories;
22
- private static HashSet<string> standardProperties;
23
-
24
- /// <summary>
25
- /// Gets the table definitions stored in this assembly.
26
- /// </summary>
27
- /// <returns>Table definition collection for tables stored in this assembly.</returns>
28
- public static TableDefinitionCollection GetTableDefinitions()
29
- {
30
- lock (lockObject)
31
- {
32
- if (null == WindowsInstallerStandard.tableDefinitions)
33
- {
34
- using (XmlReader reader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream("WixToolset.Data.WindowsInstaller.Data.tables.xml")))
35
- {
36
- tableDefinitions = TableDefinitionCollection.Load(reader);
37
- }
38
- }
39
- }
40
-
41
- return WindowsInstallerStandard.tableDefinitions;
42
- }
43
-
44
- /// <summary>
45
- /// Gets the standard actions stored in this assembly.
46
- /// </summary>
47
- /// <returns>Collection of standard actions in this assembly.</returns>
48
- public static WixActionRowCollection GetStandardActions()
49
- {
50
- lock (lockObject)
51
- {
52
- if (null == standardActions)
53
- {
54
- using (XmlReader reader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream("WixToolset.Data.WindowsInstaller.Data.actions.xml")))
55
- {
56
- standardActions = WixActionRowCollection.Load(reader);
57
- }
58
- }
59
- }
60
-
61
- return standardActions;
62
- }
63
-
64
- /// <summary>
65
- /// Gets (and loads if not yet loaded) the list of standard MSI directories.
66
- /// </summary>
67
- /// <value>The list of standard MSI directories.</value>
68
- public static HashSet<string> GetStandardDirectories()
69
- {
70
- lock (lockObject)
71
- {
72
- if (null == standardDirectories)
73
- {
74
- LoadStandardDirectories();
75
- }
76
- }
77
-
78
- return standardDirectories;
79
- }
80
-
81
- /// <summary>
82
- /// Find out if an action is a standard action.
83
- /// </summary>
84
- /// <param name="actionName">Name of the action.</param>
85
- /// <returns>true if the action is standard, false otherwise.</returns>
86
- public static bool IsStandardAction(string actionName)
87
- {
88
- lock (lockObject)
89
- {
90
- if (null == standardActionNames)
91
- {
92
- standardActionNames = new HashSet<string>();
93
- standardActionNames.Add("AllocateRegistrySpace");
94
- standardActionNames.Add("AppSearch");
95
- standardActionNames.Add("BindImage");
96
- standardActionNames.Add("CCPSearch");
97
- standardActionNames.Add("CostFinalize");
98
- standardActionNames.Add("CostInitialize");
99
- standardActionNames.Add("CreateFolders");
100
- standardActionNames.Add("CreateShortcuts");
101
- standardActionNames.Add("DeleteServices");
102
- standardActionNames.Add("DisableRollback");
103
- standardActionNames.Add("DuplicateFiles");
104
- standardActionNames.Add("ExecuteAction");
105
- standardActionNames.Add("FileCost");
106
- standardActionNames.Add("FindRelatedProducts");
107
- standardActionNames.Add("ForceReboot");
108
- standardActionNames.Add("InstallAdminPackage");
109
- standardActionNames.Add("InstallExecute");
110
- standardActionNames.Add("InstallExecuteAgain");
111
- standardActionNames.Add("InstallFiles");
112
- standardActionNames.Add("InstallFinalize");
113
- standardActionNames.Add("InstallInitialize");
114
- standardActionNames.Add("InstallODBC");
115
- standardActionNames.Add("InstallServices");
116
- standardActionNames.Add("InstallSFPCatalogFile");
117
- standardActionNames.Add("InstallValidate");
118
- standardActionNames.Add("IsolateComponents");
119
- standardActionNames.Add("LaunchConditions");
120
- standardActionNames.Add("MigrateFeatureStates");
121
- standardActionNames.Add("MoveFiles");
122
- standardActionNames.Add("MsiConfigureServices");
123
- standardActionNames.Add("MsiPublishAssemblies");
124
- standardActionNames.Add("MsiUnpublishAssemblies");
125
- standardActionNames.Add("PatchFiles");
126
- standardActionNames.Add("ProcessComponents");
127
- standardActionNames.Add("PublishComponents");
128
- standardActionNames.Add("PublishFeatures");
129
- standardActionNames.Add("PublishProduct");
130
- standardActionNames.Add("RegisterClassInfo");
131
- standardActionNames.Add("RegisterComPlus");
132
- standardActionNames.Add("RegisterExtensionInfo");
133
- standardActionNames.Add("RegisterFonts");
134
- standardActionNames.Add("RegisterMIMEInfo");
135
- standardActionNames.Add("RegisterProduct");
136
- standardActionNames.Add("RegisterProgIdInfo");
137
- standardActionNames.Add("RegisterTypeLibraries");
138
- standardActionNames.Add("RegisterUser");
139
- standardActionNames.Add("RemoveDuplicateFiles");
140
- standardActionNames.Add("RemoveEnvironmentStrings");
141
- standardActionNames.Add("RemoveExistingProducts");
142
- standardActionNames.Add("RemoveFiles");
143
- standardActionNames.Add("RemoveFolders");
144
- standardActionNames.Add("RemoveIniValues");
145
- standardActionNames.Add("RemoveODBC");
146
- standardActionNames.Add("RemoveRegistryValues");
147
- standardActionNames.Add("RemoveShortcuts");
148
- standardActionNames.Add("ResolveSource");
149
- standardActionNames.Add("RMCCPSearch");
150
- standardActionNames.Add("ScheduleReboot");
151
- standardActionNames.Add("SelfRegModules");
152
- standardActionNames.Add("SelfUnregModules");
153
- standardActionNames.Add("SetODBCFolders");
154
- standardActionNames.Add("StartServices");
155
- standardActionNames.Add("StopServices");
156
- standardActionNames.Add("UnpublishComponents");
157
- standardActionNames.Add("UnpublishFeatures");
158
- standardActionNames.Add("UnregisterClassInfo");
159
- standardActionNames.Add("UnregisterComPlus");
160
- standardActionNames.Add("UnregisterExtensionInfo");
161
- standardActionNames.Add("UnregisterFonts");
162
- standardActionNames.Add("UnregisterMIMEInfo");
163
- standardActionNames.Add("UnregisterProgIdInfo");
164
- standardActionNames.Add("UnregisterTypeLibraries");
165
- standardActionNames.Add("ValidateProductID");
166
- standardActionNames.Add("WriteEnvironmentStrings");
167
- standardActionNames.Add("WriteIniValues");
168
- standardActionNames.Add("WriteRegistryValues");
169
- }
170
- }
171
-
172
- return standardActionNames.Contains(actionName);
173
- }
174
-
175
- /// <summary>
176
- /// Find out if a directory is a standard directory.
177
- /// </summary>
178
- /// <param name="directoryName">Name of the directory.</param>
179
- /// <returns>true if the directory is standard, false otherwise.</returns>
180
- public static bool IsStandardDirectory(string directoryName)
181
- {
182
- lock (lockObject)
183
- {
184
- if (null == standardDirectories)
185
- {
186
- LoadStandardDirectories();
187
- }
188
- }
189
-
190
- return standardDirectories.Contains(directoryName);
191
- }
192
-
193
- /// <summary>
194
- /// Find out if a property is a standard property.
195
- /// References:
196
- /// Title: Property Reference [Windows Installer]:
197
- /// URL: http://msdn.microsoft.com/library/en-us/msi/setup/property_reference.asp
198
- /// </summary>
199
- /// <param name="propertyName">Name of the property.</param>
200
- /// <returns>true if a property is standard, false otherwise.</returns>
201
- public static bool IsStandardProperty(string propertyName)
202
- {
203
- lock (lockObject)
204
- {
205
- if (null == standardProperties)
206
- {
207
- standardProperties = new HashSet<string>();
208
- standardProperties.Add("~"); // REG_MULTI_SZ/NULL marker
209
- standardProperties.Add("ACTION");
210
- standardProperties.Add("ADDDEFAULT");
211
- standardProperties.Add("ADDLOCAL");
212
- standardProperties.Add("ADDDSOURCE");
213
- standardProperties.Add("AdminProperties");
214
- standardProperties.Add("AdminUser");
215
- standardProperties.Add("ADVERTISE");
216
- standardProperties.Add("AFTERREBOOT");
217
- standardProperties.Add("AllowProductCodeMismatches");
218
- standardProperties.Add("AllowProductVersionMajorMismatches");
219
- standardProperties.Add("ALLUSERS");
220
- standardProperties.Add("Alpha");
221
- standardProperties.Add("ApiPatchingSymbolFlags");
222
- standardProperties.Add("ARPAUTHORIZEDCDFPREFIX");
223
- standardProperties.Add("ARPCOMMENTS");
224
- standardProperties.Add("ARPCONTACT");
225
- standardProperties.Add("ARPHELPLINK");
226
- standardProperties.Add("ARPHELPTELEPHONE");
227
- standardProperties.Add("ARPINSTALLLOCATION");
228
- standardProperties.Add("ARPNOMODIFY");
229
- standardProperties.Add("ARPNOREMOVE");
230
- standardProperties.Add("ARPNOREPAIR");
231
- standardProperties.Add("ARPPRODUCTIONICON");
232
- standardProperties.Add("ARPREADME");
233
- standardProperties.Add("ARPSIZE");
234
- standardProperties.Add("ARPSYSTEMCOMPONENT");
235
- standardProperties.Add("ARPULRINFOABOUT");
236
- standardProperties.Add("ARPURLUPDATEINFO");
237
- standardProperties.Add("AVAILABLEFREEREG");
238
- standardProperties.Add("BorderSize");
239
- standardProperties.Add("BorderTop");
240
- standardProperties.Add("CaptionHeight");
241
- standardProperties.Add("CCP_DRIVE");
242
- standardProperties.Add("ColorBits");
243
- standardProperties.Add("COMPADDLOCAL");
244
- standardProperties.Add("COMPADDSOURCE");
245
- standardProperties.Add("COMPANYNAME");
246
- standardProperties.Add("ComputerName");
247
- standardProperties.Add("CostingComplete");
248
- standardProperties.Add("Date");
249
- standardProperties.Add("DefaultUIFont");
250
- standardProperties.Add("DISABLEADVTSHORTCUTS");
251
- standardProperties.Add("DISABLEMEDIA");
252
- standardProperties.Add("DISABLEROLLBACK");
253
- standardProperties.Add("DiskPrompt");
254
- standardProperties.Add("DontRemoveTempFolderWhenFinished");
255
- standardProperties.Add("EnableUserControl");
256
- standardProperties.Add("EXECUTEACTION");
257
- standardProperties.Add("EXECUTEMODE");
258
- standardProperties.Add("FASTOEM");
259
- standardProperties.Add("FILEADDDEFAULT");
260
- standardProperties.Add("FILEADDLOCAL");
261
- standardProperties.Add("FILEADDSOURCE");
262
- standardProperties.Add("IncludeWholeFilesOnly");
263
- standardProperties.Add("Installed");
264
- standardProperties.Add("INSTALLLEVEL");
265
- standardProperties.Add("Intel");
266
- standardProperties.Add("Intel64");
267
- standardProperties.Add("IsAdminPackage");
268
- standardProperties.Add("LeftUnit");
269
- standardProperties.Add("LIMITUI");
270
- standardProperties.Add("ListOfPatchGUIDsToReplace");
271
- standardProperties.Add("ListOfTargetProductCode");
272
- standardProperties.Add("LOGACTION");
273
- standardProperties.Add("LogonUser");
274
- standardProperties.Add("Manufacturer");
275
- standardProperties.Add("MEDIAPACKAGEPATH");
276
- standardProperties.Add("MediaSourceDir");
277
- standardProperties.Add("MinimumRequiredMsiVersion");
278
- standardProperties.Add("MsiAMD64");
279
- standardProperties.Add("MSIAPRSETTINGSIDENTIFIER");
280
- standardProperties.Add("MSICHECKCRCS");
281
- standardProperties.Add("MSIDISABLERMRESTART");
282
- standardProperties.Add("MSIENFORCEUPGRADECOMPONENTRULES");
283
- standardProperties.Add("MSIFASTINSTALL");
284
- standardProperties.Add("MsiFileToUseToCreatePatchTables");
285
- standardProperties.Add("MsiHiddenProperties");
286
- standardProperties.Add("MSIINSTALLPERUSER");
287
- standardProperties.Add("MSIINSTANCEGUID");
288
- standardProperties.Add("MsiLogFileLocation");
289
- standardProperties.Add("MsiLogging");
290
- standardProperties.Add("MsiNetAssemblySupport");
291
- standardProperties.Add("MSINEWINSTANCE");
292
- standardProperties.Add("MSINODISABLEMEDIA");
293
- standardProperties.Add("MsiNTProductType");
294
- standardProperties.Add("MsiNTSuiteBackOffice");
295
- standardProperties.Add("MsiNTSuiteDataCenter");
296
- standardProperties.Add("MsiNTSuiteEnterprise");
297
- standardProperties.Add("MsiNTSuiteSmallBusiness");
298
- standardProperties.Add("MsiNTSuiteSmallBusinessRestricted");
299
- standardProperties.Add("MsiNTSuiteWebServer");
300
- standardProperties.Add("MsiNTSuitePersonal");
301
- standardProperties.Add("MsiPatchRemovalList");
302
- standardProperties.Add("MSIPATCHREMOVE");
303
- standardProperties.Add("MSIRESTARTMANAGERCONTROL");
304
- standardProperties.Add("MsiRestartManagerSessionKey");
305
- standardProperties.Add("MSIRMSHUTDOWN");
306
- standardProperties.Add("MsiRunningElevated");
307
- standardProperties.Add("MsiUIHideCancel");
308
- standardProperties.Add("MsiUIProgressOnly");
309
- standardProperties.Add("MsiUISourceResOnly");
310
- standardProperties.Add("MsiSystemRebootPending");
311
- standardProperties.Add("MsiWin32AssemblySupport");
312
- standardProperties.Add("NOCOMPANYNAME");
313
- standardProperties.Add("NOUSERNAME");
314
- standardProperties.Add("OLEAdvtSupport");
315
- standardProperties.Add("OptimizePatchSizeForLargeFiles");
316
- standardProperties.Add("OriginalDatabase");
317
- standardProperties.Add("OutOfDiskSpace");
318
- standardProperties.Add("OutOfNoRbDiskSpace");
319
- standardProperties.Add("ParentOriginalDatabase");
320
- standardProperties.Add("ParentProductCode");
321
- standardProperties.Add("PATCH");
322
- standardProperties.Add("PATCH_CACHE_DIR");
323
- standardProperties.Add("PATCH_CACHE_ENABLED");
324
- standardProperties.Add("PatchGUID");
325
- standardProperties.Add("PATCHNEWPACKAGECODE");
326
- standardProperties.Add("PATCHNEWSUMMARYCOMMENTS");
327
- standardProperties.Add("PATCHNEWSUMMARYSUBJECT");
328
- standardProperties.Add("PatchOutputPath");
329
- standardProperties.Add("PatchSourceList");
330
- standardProperties.Add("PhysicalMemory");
331
- standardProperties.Add("PIDKEY");
332
- standardProperties.Add("PIDTemplate");
333
- standardProperties.Add("Preselected");
334
- standardProperties.Add("PRIMARYFOLDER");
335
- standardProperties.Add("PrimaryVolumePath");
336
- standardProperties.Add("PrimaryVolumeSpaceAvailable");
337
- standardProperties.Add("PrimaryVolumeSpaceRemaining");
338
- standardProperties.Add("PrimaryVolumeSpaceRequired");
339
- standardProperties.Add("Privileged");
340
- standardProperties.Add("ProductCode");
341
- standardProperties.Add("ProductID");
342
- standardProperties.Add("ProductLanguage");
343
- standardProperties.Add("ProductName");
344
- standardProperties.Add("ProductState");
345
- standardProperties.Add("ProductVersion");
346
- standardProperties.Add("PROMPTROLLBACKCOST");
347
- standardProperties.Add("REBOOT");
348
- standardProperties.Add("REBOOTPROMPT");
349
- standardProperties.Add("RedirectedDllSupport");
350
- standardProperties.Add("REINSTALL");
351
- standardProperties.Add("REINSTALLMODE");
352
- standardProperties.Add("RemoveAdminTS");
353
- standardProperties.Add("REMOVE");
354
- standardProperties.Add("ReplacedInUseFiles");
355
- standardProperties.Add("RestrictedUserControl");
356
- standardProperties.Add("RESUME");
357
- standardProperties.Add("RollbackDisabled");
358
- standardProperties.Add("ROOTDRIVE");
359
- standardProperties.Add("ScreenX");
360
- standardProperties.Add("ScreenY");
361
- standardProperties.Add("SecureCustomProperties");
362
- standardProperties.Add("ServicePackLevel");
363
- standardProperties.Add("ServicePackLevelMinor");
364
- standardProperties.Add("SEQUENCE");
365
- standardProperties.Add("SharedWindows");
366
- standardProperties.Add("ShellAdvtSupport");
367
- standardProperties.Add("SHORTFILENAMES");
368
- standardProperties.Add("SourceDir");
369
- standardProperties.Add("SOURCELIST");
370
- standardProperties.Add("SystemLanguageID");
371
- standardProperties.Add("TARGETDIR");
372
- standardProperties.Add("TerminalServer");
373
- standardProperties.Add("TextHeight");
374
- standardProperties.Add("Time");
375
- standardProperties.Add("TRANSFORMS");
376
- standardProperties.Add("TRANSFORMSATSOURCE");
377
- standardProperties.Add("TRANSFORMSSECURE");
378
- standardProperties.Add("TTCSupport");
379
- standardProperties.Add("UILevel");
380
- standardProperties.Add("UpdateStarted");
381
- standardProperties.Add("UpgradeCode");
382
- standardProperties.Add("UPGRADINGPRODUCTCODE");
383
- standardProperties.Add("UserLanguageID");
384
- standardProperties.Add("USERNAME");
385
- standardProperties.Add("UserSID");
386
- standardProperties.Add("Version9X");
387
- standardProperties.Add("VersionDatabase");
388
- standardProperties.Add("VersionMsi");
389
- standardProperties.Add("VersionNT");
390
- standardProperties.Add("VersionNT64");
391
- standardProperties.Add("VirtualMemory");
392
- standardProperties.Add("WindowsBuild");
393
- standardProperties.Add("WindowsVolume");
394
- }
395
- }
396
-
397
- return standardProperties.Contains(propertyName);
398
- }
399
-
400
- /// <summary>
401
- /// Sets up a hashtable with the set of standard MSI directories
402
- /// </summary>
403
- private static void LoadStandardDirectories()
404
- {
405
- lock (lockObject)
406
- {
407
- if (null == standardDirectories)
408
- {
409
- standardDirectories = new HashSet<string>();
410
- standardDirectories.Add("TARGETDIR");
411
- standardDirectories.Add("AdminToolsFolder");
412
- standardDirectories.Add("AppDataFolder");
413
- standardDirectories.Add("CommonAppDataFolder");
414
- standardDirectories.Add("CommonFilesFolder");
415
- standardDirectories.Add("DesktopFolder");
416
- standardDirectories.Add("FavoritesFolder");
417
- standardDirectories.Add("FontsFolder");
418
- standardDirectories.Add("LocalAppDataFolder");
419
- standardDirectories.Add("MyPicturesFolder");
420
- standardDirectories.Add("PersonalFolder");
421
- standardDirectories.Add("ProgramFilesFolder");
422
- standardDirectories.Add("ProgramMenuFolder");
423
- standardDirectories.Add("SendToFolder");
424
- standardDirectories.Add("StartMenuFolder");
425
- standardDirectories.Add("StartupFolder");
426
- standardDirectories.Add("System16Folder");
427
- standardDirectories.Add("SystemFolder");
428
- standardDirectories.Add("TempFolder");
429
- standardDirectories.Add("TemplateFolder");
430
- standardDirectories.Add("WindowsFolder");
431
- standardDirectories.Add("CommonFiles64Folder");
432
- standardDirectories.Add("ProgramFiles64Folder");
433
- standardDirectories.Add("System64Folder");
434
- standardDirectories.Add("NetHoodFolder");
435
- standardDirectories.Add("PrintHoodFolder");
436
- standardDirectories.Add("RecentFolder");
437
- standardDirectories.Add("WindowsVolume");
438
- }
439
- }
440
- }
441
- }
442
-}
src/WixToolset.Data.WindowsInstaller/WindowsInstallerStandardInternal.cs
new
+59
@@ -0,0 +1,59 @@
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.Data
4
+{
5
+ using System.Reflection;
6
+ using System.Xml;
7
+ using WixToolset.Data.Rows;
8
+
9
+ /// <summary>
10
+ /// Represents the Windows Installer standard objects.
11
+ /// </summary>
12
+ public static class WindowsInstallerStandardInternal
13
+ {
14
+ private static readonly object lockObject = new object();
15
+
16
+ private static TableDefinitionCollection tableDefinitions;
17
+ private static WixActionRowCollection standardActions;
18
+
19
+ /// <summary>
20
+ /// Gets the table definitions stored in this assembly.
21
+ /// </summary>
22
+ /// <returns>Table definition collection for tables stored in this assembly.</returns>
23
+ public static TableDefinitionCollection GetTableDefinitions()
24
+ {
25
+ lock (lockObject)
26
+ {
27
+ if (null == WindowsInstallerStandardInternal.tableDefinitions)
28
+ {
29
+ using (XmlReader reader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream("WixToolset.Data.WindowsInstaller.Data.tables.xml")))
30
+ {
31
+ WindowsInstallerStandardInternal.tableDefinitions = TableDefinitionCollection.Load(reader);
32
+ }
33
+ }
34
+ }
35
+
36
+ return WindowsInstallerStandardInternal.tableDefinitions;
37
+ }
38
+
39
+ /// <summary>
40
+ /// Gets the standard actions stored in this assembly.
41
+ /// </summary>
42
+ /// <returns>Collection of standard actions in this assembly.</returns>
43
+ public static WixActionRowCollection GetStandardActionRows()
44
+ {
45
+ lock (lockObject)
46
+ {
47
+ if (null == WindowsInstallerStandardInternal.standardActions)
48
+ {
49
+ using (XmlReader reader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream("WixToolset.Data.WindowsInstaller.Data.actions.xml")))
50
+ {
51
+ WindowsInstallerStandardInternal.standardActions = WixActionRowCollection.Load(reader);
52
+ }
53
+ }
54
+ }
55
+
56
+ return WindowsInstallerStandardInternal.standardActions;
57
+ }
58
+ }
59
+}
src/test/WixToolsetTest.CoreIntegrationFixture/ProgramFixture.cs
+3
-4
@@ -26,18 +26,17 @@ namespace WixToolsetTest.CoreIntegrationFixture
26
var result = program.Run(new WixToolsetServiceProvider(), new[] { "build", "Package.wxs", "PackageComponents.wxs", "-loc", "Package.en-us.wxl", "-bindpath", "data", "-intermediateFolder", intermediateFolder, "-o", $@"{intermediateFolder}\bin\test.msi" });
27
28
Assert.Equal(0, result);
29
-#if FIXED_MSI_BACKEND
29
+
30
Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\test.msi")));
31
Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\test.wixpdb")));
32
Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\MsiPackage\test.txt")));
33
-#else
34
- var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"bin\test.msi"));
33
+
34
+ var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"bin\test.wir"));
35
Assert.Single(intermediate.Sections);
36
37
var wixFile = intermediate.Sections.SelectMany(s => s.Tuples).OfType<WixFileTuple>().Single();
38
Assert.Equal(@"data\test.txt", wixFile[WixFileTupleFields.Source].AsPath().Path);
39
Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path);
40
-#endif
40
}
41
}
42
}