aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core')
-rw-r--r--src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs8
-rw-r--r--src/WixToolset.Core/Bind/FileResolver.cs8
-rw-r--r--src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs2
-rw-r--r--src/WixToolset.Core/BindContext.cs4
-rw-r--r--src/WixToolset.Core/CommandLine/BuildCommand.cs11
-rw-r--r--src/WixToolset.Core/Compiler.cs2
-rw-r--r--src/WixToolset.Core/Compiler_Bundle.cs139
-rw-r--r--src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs11
-rw-r--r--src/WixToolset.Core/ExtensibilityServices/PathResolver.cs91
-rw-r--r--src/WixToolset.Core/ExtensibilityServices/ResolvedDirectory.cs15
-rw-r--r--src/WixToolset.Core/ExtensibilityServices/WindowsInstallerBackendHelper.cs32
-rw-r--r--src/WixToolset.Core/Link/WixGroupingOrdering.cs31
-rw-r--r--src/WixToolset.Core/WixToolsetServiceProvider.cs4
13 files changed, 237 insertions, 121 deletions
diff --git a/src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs b/src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs
index c6e21973..644e5c63 100644
--- a/src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs
+++ b/src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs
@@ -30,10 +30,10 @@ namespace WixToolset.Core.Bind
30 { 30 {
31 // If the uri to the file that contains the embedded file does not already have embedded files 31 // If the uri to the file that contains the embedded file does not already have embedded files
32 // being extracted, create the dictionary to track that. 32 // being extracted, create the dictionary to track that.
33 if (!filesWithEmbeddedFiles.TryGetValue(uri, out var extracts)) 33 if (!this.filesWithEmbeddedFiles.TryGetValue(uri, out var extracts))
34 { 34 {
35 extracts = new SortedList<int, string>(); 35 extracts = new SortedList<int, string>();
36 filesWithEmbeddedFiles.Add(uri, extracts); 36 this.filesWithEmbeddedFiles.Add(uri, extracts);
37 } 37 }
38 38
39 // If the embedded file is not already tracked in the dictionary of extracts, add it. 39 // If the embedded file is not already tracked in the dictionary of extracts, add it.
@@ -52,7 +52,7 @@ namespace WixToolset.Core.Bind
52 52
53 public IEnumerable<ExpectedExtractFile> GetExpectedEmbeddedFiles() 53 public IEnumerable<ExpectedExtractFile> GetExpectedEmbeddedFiles()
54 { 54 {
55 foreach (var uriWithExtracts in filesWithEmbeddedFiles) 55 foreach (var uriWithExtracts in this.filesWithEmbeddedFiles)
56 { 56 {
57 foreach (var extracts in uriWithExtracts.Value) 57 foreach (var extracts in uriWithExtracts.Value)
58 { 58 {
@@ -68,7 +68,7 @@ namespace WixToolset.Core.Bind
68 68
69 public IEnumerable<ExpectedExtractFile> GetExtractFilesForUri(Uri uri) 69 public IEnumerable<ExpectedExtractFile> GetExtractFilesForUri(Uri uri)
70 { 70 {
71 if (!filesWithEmbeddedFiles.TryGetValue(uri, out var extracts)) 71 if (!this.filesWithEmbeddedFiles.TryGetValue(uri, out var extracts))
72 { 72 {
73 extracts = new SortedList<int, string>(); 73 extracts = new SortedList<int, string>();
74 } 74 }
diff --git a/src/WixToolset.Core/Bind/FileResolver.cs b/src/WixToolset.Core/Bind/FileResolver.cs
index a67d784d..b1676fad 100644
--- a/src/WixToolset.Core/Bind/FileResolver.cs
+++ b/src/WixToolset.Core/Bind/FileResolver.cs
@@ -70,11 +70,17 @@ namespace WixToolset.Core.Bind
70 /// <param name="type">Optional type of source file being resolved.</param> 70 /// <param name="type">Optional type of source file being resolved.</param>
71 /// <param name="sourceLineNumbers">Optional source line of source file being resolved.</param> 71 /// <param name="sourceLineNumbers">Optional source line of source file being resolved.</param>
72 /// <param name="bindStage">The binding stage used to determine what collection of bind paths will be used</param> 72 /// <param name="bindStage">The binding stage used to determine what collection of bind paths will be used</param>
73 /// <param name="alreadyCheckedPaths">Optional collection of paths already checked.</param>
73 /// <returns>Should return a valid path for the stream to be imported.</returns> 74 /// <returns>Should return a valid path for the stream to be imported.</returns>
74 public string ResolveFile(string source, IntermediateTupleDefinition tupleDefinition, SourceLineNumber sourceLineNumbers, BindStage bindStage) 75 public string ResolveFile(string source, IntermediateTupleDefinition tupleDefinition, SourceLineNumber sourceLineNumbers, BindStage bindStage, IEnumerable<string> alreadyCheckedPaths = null)
75 { 76 {
76 var checkedPaths = new List<string>(); 77 var checkedPaths = new List<string>();
77 78
79 if (alreadyCheckedPaths != null)
80 {
81 checkedPaths.AddRange(alreadyCheckedPaths);
82 }
83
78 foreach (var extension in this.ResolverExtensions) 84 foreach (var extension in this.ResolverExtensions)
79 { 85 {
80 var resolved = extension.ResolveFile(source, tupleDefinition, sourceLineNumbers, bindStage); 86 var resolved = extension.ResolveFile(source, tupleDefinition, sourceLineNumbers, bindStage);
diff --git a/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs b/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs
index bec03907..22710aca 100644
--- a/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs
+++ b/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs
@@ -113,7 +113,7 @@ namespace WixToolset.Core.Bind
113 } 113 }
114 } 114 }
115 115
116 public static string ResolveDelayedVariables(SourceLineNumber sourceLineNumbers, string value, IDictionary<string, string> resolutionData) 116 private static string ResolveDelayedVariables(SourceLineNumber sourceLineNumbers, string value, IDictionary<string, string> resolutionData)
117 { 117 {
118 var matches = Common.WixVariableRegex.Matches(value); 118 var matches = Common.WixVariableRegex.Matches(value);
119 119
diff --git a/src/WixToolset.Core/BindContext.cs b/src/WixToolset.Core/BindContext.cs
index 413be301..7882b22d 100644
--- a/src/WixToolset.Core/BindContext.cs
+++ b/src/WixToolset.Core/BindContext.cs
@@ -1,4 +1,4 @@
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. 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 2
3namespace WixToolset.Core 3namespace WixToolset.Core
4{ 4{
@@ -19,6 +19,8 @@ namespace WixToolset.Core
19 19
20 public IEnumerable<BindPath> BindPaths { get; set; } 20 public IEnumerable<BindPath> BindPaths { get; set; }
21 21
22 public string BurnStubPath { get; set; }
23
22 public int CabbingThreadCount { get; set; } 24 public int CabbingThreadCount { get; set; }
23 25
24 public string CabCachePath { get; set; } 26 public string CabCachePath { get; set; }
diff --git a/src/WixToolset.Core/CommandLine/BuildCommand.cs b/src/WixToolset.Core/CommandLine/BuildCommand.cs
index bfee2478..972258fe 100644
--- a/src/WixToolset.Core/CommandLine/BuildCommand.cs
+++ b/src/WixToolset.Core/CommandLine/BuildCommand.cs
@@ -122,7 +122,7 @@ namespace WixToolset.Core.CommandLine
122 } 122 }
123 else 123 else
124 { 124 {
125 this.BindPhase(wixipl, wxls, filterCultures, this.commandLine.CabCachePath, this.commandLine.BindPaths); 125 this.BindPhase(wixipl, wxls, filterCultures, this.commandLine.CabCachePath, this.commandLine.BindPaths, this.commandLine.BurnStubPath);
126 } 126 }
127 } 127 }
128 } 128 }
@@ -257,7 +257,7 @@ namespace WixToolset.Core.CommandLine
257 return linker.Link(context); 257 return linker.Link(context);
258 } 258 }
259 259
260 private void BindPhase(Intermediate output, IEnumerable<Localization> localizations, IEnumerable<string> filterCultures, string cabCachePath, IEnumerable<IBindPath> bindPaths) 260 private void BindPhase(Intermediate output, IEnumerable<Localization> localizations, IEnumerable<string> filterCultures, string cabCachePath, IEnumerable<IBindPath> bindPaths, string burnStubPath)
261 { 261 {
262 var intermediateFolder = this.IntermediateFolder; 262 var intermediateFolder = this.IntermediateFolder;
263 if (String.IsNullOrEmpty(intermediateFolder)) 263 if (String.IsNullOrEmpty(intermediateFolder))
@@ -290,6 +290,7 @@ namespace WixToolset.Core.CommandLine
290 { 290 {
291 var context = this.ServiceProvider.GetService<IBindContext>(); 291 var context = this.ServiceProvider.GetService<IBindContext>();
292 //context.CabbingThreadCount = this.CabbingThreadCount; 292 //context.CabbingThreadCount = this.CabbingThreadCount;
293 context.BurnStubPath = burnStubPath;
293 context.CabCachePath = cabCachePath; 294 context.CabCachePath = cabCachePath;
294 context.Codepage = resolveResult.Codepage; 295 context.Codepage = resolveResult.Codepage;
295 //context.DefaultCompressionLevel = this.DefaultCompressionLevel; 296 //context.DefaultCompressionLevel = this.DefaultCompressionLevel;
@@ -399,6 +400,8 @@ namespace WixToolset.Core.CommandLine
399 400
400 public List<IBindPath> BindPaths { get; } = new List<IBindPath>(); 401 public List<IBindPath> BindPaths { get; } = new List<IBindPath>();
401 402
403 public string BurnStubPath { get; private set; }
404
402 public string CabCachePath { get; private set; } 405 public string CabCachePath { get; private set; }
403 406
404 public List<string> Cultures { get; } = new List<string>(); 407 public List<string> Cultures { get; } = new List<string>();
@@ -480,6 +483,10 @@ namespace WixToolset.Core.CommandLine
480 } 483 }
481 break; 484 break;
482 } 485 }
486 case "burnstub":
487 this.BurnStubPath = parser.GetNextArgumentOrError(arg);
488 return true;
489
483 case "cc": 490 case "cc":
484 this.CabCachePath = parser.GetNextArgumentOrError(arg); 491 this.CabCachePath = parser.GetNextArgumentOrError(arg);
485 return true; 492 return true;
diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs
index 0dade46d..3ee87872 100644
--- a/src/WixToolset.Core/Compiler.cs
+++ b/src/WixToolset.Core/Compiler.cs
@@ -818,7 +818,7 @@ namespace WixToolset.Core
818 { 818 {
819 this.Core.AddTuple(new IconTuple(sourceLineNumbers, id) 819 this.Core.AddTuple(new IconTuple(sourceLineNumbers, id)
820 { 820 {
821 Data = sourceFile 821 Data = new IntermediateFieldPathValue { Path = sourceFile }
822 }); 822 });
823 } 823 }
824 824
diff --git a/src/WixToolset.Core/Compiler_Bundle.cs b/src/WixToolset.Core/Compiler_Bundle.cs
index 0ed49fbc..3be7d0c5 100644
--- a/src/WixToolset.Core/Compiler_Bundle.cs
+++ b/src/WixToolset.Core/Compiler_Bundle.cs
@@ -9,6 +9,7 @@ namespace WixToolset.Core
9 using System.IO; 9 using System.IO;
10 using System.Xml.Linq; 10 using System.Xml.Linq;
11 using WixToolset.Data; 11 using WixToolset.Data;
12 using WixToolset.Data.Burn;
12 using WixToolset.Data.Tuples; 13 using WixToolset.Data.Tuples;
13 using WixToolset.Extensibility; 14 using WixToolset.Extensibility;
14 15
@@ -17,15 +18,9 @@ namespace WixToolset.Core
17 /// </summary> 18 /// </summary>
18 internal partial class Compiler : ICompiler 19 internal partial class Compiler : ICompiler
19 { 20 {
20 public static readonly Identifier BurnUXContainerId = new Identifier(AccessModifier.Private, "WixUXContainer"); 21 private static readonly Identifier BurnUXContainerId = new Identifier(AccessModifier.Private, BurnConstants.BurnUXContainerName);
21 public static readonly Identifier BurnDefaultAttachedContainerId = new Identifier(AccessModifier.Private, "WixAttachedContainer"); 22 private static readonly Identifier BurnDefaultAttachedContainerId = new Identifier(AccessModifier.Private, BurnConstants.BurnDefaultAttachedContainerName);
22 public static readonly Identifier BundleLayoutOnlyPayloads = new Identifier(AccessModifier.Private, "BundleLayoutOnlyPayloads"); 23 private static readonly Identifier BundleLayoutOnlyPayloads = new Identifier(AccessModifier.Private, BurnConstants.BundleLayoutOnlyPayloadsName);
23
24 // The following constants must stay in sync with src\burn\engine\core.h
25 private const string BURN_BUNDLE_NAME = "WixBundleName";
26 private const string BURN_BUNDLE_ORIGINAL_SOURCE = "WixBundleOriginalSource";
27 private const string BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER = "WixBundleOriginalSourceFolder";
28 private const string BURN_BUNDLE_LAST_USED_SOURCE = "WixBundleLastUsedSource";
29 24
30 /// <summary> 25 /// <summary>
31 /// Parses an ApprovedExeForElevation element. 26 /// Parses an ApprovedExeForElevation element.
@@ -78,11 +73,11 @@ namespace WixToolset.Core
78 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key")); 73 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key"));
79 } 74 }
80 75
81 var attributes = BundleApprovedExeForElevationAttributes.None; 76 var attributes = WixApprovedExeForElevationAttributes.None;
82 77
83 if (win64 == YesNoType.Yes) 78 if (win64 == YesNoType.Yes)
84 { 79 {
85 attributes |= BundleApprovedExeForElevationAttributes.Win64; 80 attributes |= WixApprovedExeForElevationAttributes.Win64;
86 } 81 }
87 82
88 this.Core.ParseForExtensionElements(node); 83 this.Core.ParseForExtensionElements(node);
@@ -92,7 +87,7 @@ namespace WixToolset.Core
92 var tuple = new WixApprovedExeForElevationTuple(sourceLineNumbers, id) 87 var tuple = new WixApprovedExeForElevationTuple(sourceLineNumbers, id)
93 { 88 {
94 Key = key, 89 Key = key,
95 Value = valueName, 90 ValueName = valueName,
96 Attributes = attributes 91 Attributes = attributes
97 }; 92 };
98 93
@@ -110,8 +105,7 @@ namespace WixToolset.Core
110 string copyright = null; 105 string copyright = null;
111 string aboutUrl = null; 106 string aboutUrl = null;
112 var compressed = YesNoDefaultType.Default; 107 var compressed = YesNoDefaultType.Default;
113 var disableModify = -1; 108 WixBundleAttributes attributes = 0;
114 var disableRemove = YesNoType.NotSet;
115 string helpTelephone = null; 109 string helpTelephone = null;
116 string helpUrl = null; 110 string helpUrl = null;
117 string manufacturer = null; 111 string manufacturer = null;
@@ -152,13 +146,12 @@ namespace WixToolset.Core
152 switch (value) 146 switch (value)
153 { 147 {
154 case "button": 148 case "button":
155 disableModify = 2; 149 attributes |= WixBundleAttributes.SingleChangeUninstallButton;
156 break; 150 break;
157 case "yes": 151 case "yes":
158 disableModify = 1; 152 attributes |= WixBundleAttributes.DisableModify;
159 break; 153 break;
160 case "no": 154 case "no":
161 disableModify = 0;
162 break; 155 break;
163 default: 156 default:
164 this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, value, "button", "yes", "no")); 157 this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, value, "button", "yes", "no"));
@@ -166,10 +159,10 @@ namespace WixToolset.Core
166 } 159 }
167 break; 160 break;
168 case "DisableRemove": 161 case "DisableRemove":
169 disableRemove = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 162 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
170 break; 163 {
171 case "DisableRepair": 164 attributes |= WixBundleAttributes.DisableRemove;
172 this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); 165 }
173 break; 166 break;
174 case "HelpTelephone": 167 case "HelpTelephone":
175 helpTelephone = this.Core.GetAttributeValue(sourceLineNumbers, attrib); 168 helpTelephone = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -239,13 +232,13 @@ namespace WixToolset.Core
239 232
240 if (String.IsNullOrEmpty(name)) 233 if (String.IsNullOrEmpty(name))
241 { 234 {
242 logVariablePrefixAndExtension = String.Concat("WixBundleLog:Setup.log"); 235 logVariablePrefixAndExtension = String.Concat("WixBundleLog:Setup:.log");
243 } 236 }
244 else 237 else
245 { 238 {
246 // Ensure only allowable path characters are in "name" (and change spaces to underscores). 239 // Ensure only allowable path characters are in "name" (and change spaces to underscores).
247 fileSystemSafeBundleName = CompilerCore.MakeValidLongFileName(name.Replace(' ', '_'), "_"); 240 fileSystemSafeBundleName = CompilerCore.MakeValidLongFileName(name.Replace(' ', '_'), "_");
248 logVariablePrefixAndExtension = String.Concat("WixBundleLog:", fileSystemSafeBundleName, ".log"); 241 logVariablePrefixAndExtension = String.Concat("WixBundleLog:", fileSystemSafeBundleName, ":.log");
249 } 242 }
250 243
251 this.activeName = String.IsNullOrEmpty(name) ? Common.GenerateGuid() : name; 244 this.activeName = String.IsNullOrEmpty(name) ? Common.GenerateGuid() : name;
@@ -351,6 +344,37 @@ namespace WixToolset.Core
351 344
352 if (!this.Core.EncounteredError) 345 if (!this.Core.EncounteredError)
353 { 346 {
347 var tuple = new WixBundleTuple(sourceLineNumbers)
348 {
349 UpgradeCode = upgradeCode,
350 Version = version,
351 Copyright = copyright,
352 Name = name,
353 Manufacturer = manufacturer,
354 Attributes = attributes,
355 AboutUrl = aboutUrl,
356 HelpUrl = helpUrl,
357 HelpTelephone = helpTelephone,
358 UpdateUrl = updateUrl,
359 Compressed = YesNoDefaultType.Yes == compressed ? true : YesNoDefaultType.No == compressed ? (bool?)false : null,
360 IconSourceFile = iconSourceFile,
361 SplashScreenSourceFile = splashScreenSourceFile,
362 Condition = condition,
363 Tag = tag,
364 Platform = this.CurrentPlatform,
365 ParentName = parentName,
366 };
367
368 if (!String.IsNullOrEmpty(logVariablePrefixAndExtension))
369 {
370 var split = logVariablePrefixAndExtension.Split(':');
371 tuple.LogPathVariable = split[0];
372 tuple.LogPrefix = split[1];
373 tuple.LogExtension = split[2];
374 }
375
376 this.Core.AddTuple(tuple);;
377
354 if (null != upgradeCode) 378 if (null != upgradeCode)
355 { 379 {
356 this.Core.AddTuple(new WixRelatedBundleTuple(sourceLineNumbers) 380 this.Core.AddTuple(new WixRelatedBundleTuple(sourceLineNumbers)
@@ -360,64 +384,32 @@ namespace WixToolset.Core
360 }); 384 });
361 } 385 }
362 386
363 this.Core.AddTuple(new WixBundleContainerTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BurnDefaultAttachedContainerId)) 387 this.Core.AddTuple(new WixBundleContainerTuple(sourceLineNumbers, Compiler.BurnDefaultAttachedContainerId)
364 { 388 {
365 Name = "bundle-attached.cab", 389 Name = "bundle-attached.cab",
366 Type = ContainerType.Attached 390 Type = ContainerType.Attached
367 }); 391 });
368 392
369 var bundleTuple = this.Core.CreateTuple(sourceLineNumbers, TupleDefinitionType.WixBundle);
370 bundleTuple.Set(0, version);
371 bundleTuple.Set(1, copyright);
372 bundleTuple.Set(2, name);
373 bundleTuple.Set(3, aboutUrl);
374 if (-1 != disableModify)
375 {
376 bundleTuple.Set(4, disableModify);
377 }
378 if (YesNoType.NotSet != disableRemove)
379 {
380 bundleTuple.Set(5, (YesNoType.Yes == disableRemove) ? 1 : 0);
381 }
382 // row.Set(6] - (deprecated) "disable repair"
383 bundleTuple.Set(7, helpTelephone);
384 bundleTuple.Set(8, helpUrl);
385 bundleTuple.Set(9, manufacturer);
386 bundleTuple.Set(10, updateUrl);
387 if (YesNoDefaultType.Default != compressed)
388 {
389 bundleTuple.Set(11, (YesNoDefaultType.Yes == compressed) ? 1 : 0);
390 }
391
392 bundleTuple.Set(12, logVariablePrefixAndExtension);
393 bundleTuple.Set(13, iconSourceFile);
394 bundleTuple.Set(14, splashScreenSourceFile);
395 bundleTuple.Set(15, condition);
396 bundleTuple.Set(16, tag);
397 bundleTuple.Set(17, this.CurrentPlatform.ToString());
398 bundleTuple.Set(18, parentName);
399 bundleTuple.Set(19, upgradeCode);
400
401 // Ensure that the bundle stores the well-known persisted values. 393 // Ensure that the bundle stores the well-known persisted values.
402 this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BURN_BUNDLE_NAME)) 394 this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, BurnConstants.BURN_BUNDLE_NAME))
403 { 395 {
404 Hidden = false, 396 Hidden = false,
405 Persisted = true 397 Persisted = true
406 }); 398 });
407 399
408 this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BURN_BUNDLE_ORIGINAL_SOURCE)) 400 this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, BurnConstants.BURN_BUNDLE_ORIGINAL_SOURCE))
409 { 401 {
410 Hidden = false, 402 Hidden = false,
411 Persisted = true 403 Persisted = true
412 }); 404 });
413 405
414 this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER)) 406 this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, BurnConstants.BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER))
415 { 407 {
416 Hidden = false, 408 Hidden = false,
417 Persisted = true 409 Persisted = true
418 }); 410 });
419 411
420 this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BURN_BUNDLE_LAST_USED_SOURCE)) 412 this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, BurnConstants.BURN_BUNDLE_LAST_USED_SOURCE))
421 { 413 {
422 Hidden = false, 414 Hidden = false,
423 Persisted = true 415 Persisted = true
@@ -473,7 +465,7 @@ namespace WixToolset.Core
473 465
474 this.Core.ParseForExtensionElements(node); 466 this.Core.ParseForExtensionElements(node);
475 467
476 return YesNoType.Yes == disableLog ? null : String.Concat(variable, ":", logPrefix, logExtension); 468 return YesNoType.Yes == disableLog ? null : String.Join(":", variable, logPrefix, logExtension);
477 } 469 }
478 470
479 /// <summary> 471 /// <summary>
@@ -1126,9 +1118,9 @@ namespace WixToolset.Core
1126 tuple = new WixBundlePayloadTuple(sourceLineNumbers, id) 1118 tuple = new WixBundlePayloadTuple(sourceLineNumbers, id)
1127 { 1119 {
1128 Name = String.IsNullOrEmpty(name) ? Path.GetFileName(sourceFile) : name, 1120 Name = String.IsNullOrEmpty(name) ? Path.GetFileName(sourceFile) : name,
1129 SourceFile = sourceFile, 1121 SourceFile = new IntermediateFieldPathValue { Path = sourceFile },
1130 DownloadUrl = downloadUrl, 1122 DownloadUrl = downloadUrl,
1131 Compressed = compressed, 1123 Compressed = (compressed == YesNoDefaultType.Yes) ? true : (compressed == YesNoDefaultType.No) ? (bool?)false : null,
1132 UnresolvedSourceFile = sourceFile, // duplicate of sourceFile but in a string column so it won't get resolved to a full path during binding. 1124 UnresolvedSourceFile = sourceFile, // duplicate of sourceFile but in a string column so it won't get resolved to a full path during binding.
1133 DisplayName = displayName, 1125 DisplayName = displayName,
1134 Description = description, 1126 Description = description,
@@ -1665,14 +1657,12 @@ namespace WixToolset.Core
1665 var vital = YesNoType.Yes; 1657 var vital = YesNoType.Yes;
1666 string installCommand = null; 1658 string installCommand = null;
1667 string repairCommand = null; 1659 string repairCommand = null;
1668 var repairable = YesNoType.NotSet;
1669 string uninstallCommand = null; 1660 string uninstallCommand = null;
1670 var perMachine = YesNoDefaultType.NotSet; 1661 var perMachine = YesNoDefaultType.NotSet;
1671 string detectCondition = null; 1662 string detectCondition = null;
1672 string protocol = null; 1663 string protocol = null;
1673 var installSize = CompilerConstants.IntegerNotSet; 1664 var installSize = CompilerConstants.IntegerNotSet;
1674 string msuKB = null; 1665 string msuKB = null;
1675 var suppressLooseFilePayloadGeneration = YesNoType.NotSet;
1676 var enableSignatureVerification = YesNoType.No; 1666 var enableSignatureVerification = YesNoType.No;
1677 var compressed = YesNoDefaultType.Default; 1667 var compressed = YesNoDefaultType.Default;
1678 var displayInternalUI = YesNoType.NotSet; 1668 var displayInternalUI = YesNoType.NotSet;
@@ -1779,7 +1769,6 @@ namespace WixToolset.Core
1779 break; 1769 break;
1780 case "RepairCommand": 1770 case "RepairCommand":
1781 repairCommand = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 1771 repairCommand = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
1782 repairable = YesNoType.Yes;
1783 allowed = (packageType == WixBundlePackageType.Exe); 1772 allowed = (packageType == WixBundlePackageType.Exe);
1784 break; 1773 break;
1785 case "UninstallCommand": 1774 case "UninstallCommand":
@@ -1808,11 +1797,6 @@ namespace WixToolset.Core
1808 case "Compressed": 1797 case "Compressed":
1809 compressed = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); 1798 compressed = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
1810 break; 1799 break;
1811 case "SuppressLooseFilePayloadGeneration":
1812 this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
1813 suppressLooseFilePayloadGeneration = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1814 allowed = (packageType == WixBundlePackageType.Msi);
1815 break;
1816 case "EnableSignatureVerification": 1800 case "EnableSignatureVerification":
1817 enableSignatureVerification = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 1801 enableSignatureVerification = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1818 break; 1802 break;
@@ -2076,7 +2060,7 @@ namespace WixToolset.Core
2076 case WixBundlePackageType.Exe: 2060 case WixBundlePackageType.Exe:
2077 this.Core.AddTuple(new WixBundleExePackageTuple(sourceLineNumbers, id) 2061 this.Core.AddTuple(new WixBundleExePackageTuple(sourceLineNumbers, id)
2078 { 2062 {
2079 Attributes = (YesNoType.Yes == repairable) ? WixBundleExePackageAttributes.Repairable : 0, 2063 Attributes = WixBundleExePackageAttributes.None,
2080 DetectCondition = detectCondition, 2064 DetectCondition = detectCondition,
2081 InstallCommand = installCommand, 2065 InstallCommand = installCommand,
2082 RepairCommand = repairCommand, 2066 RepairCommand = repairCommand,
@@ -2090,7 +2074,6 @@ namespace WixToolset.Core
2090 msiAttributes |= (YesNoType.Yes == displayInternalUI) ? WixBundleMsiPackageAttributes.DisplayInternalUI : 0; 2074 msiAttributes |= (YesNoType.Yes == displayInternalUI) ? WixBundleMsiPackageAttributes.DisplayInternalUI : 0;
2091 msiAttributes |= (YesNoType.Yes == enableFeatureSelection) ? WixBundleMsiPackageAttributes.EnableFeatureSelection : 0; 2075 msiAttributes |= (YesNoType.Yes == enableFeatureSelection) ? WixBundleMsiPackageAttributes.EnableFeatureSelection : 0;
2092 msiAttributes |= (YesNoType.Yes == forcePerMachine) ? WixBundleMsiPackageAttributes.ForcePerMachine : 0; 2076 msiAttributes |= (YesNoType.Yes == forcePerMachine) ? WixBundleMsiPackageAttributes.ForcePerMachine : 0;
2093 msiAttributes |= (YesNoType.Yes == suppressLooseFilePayloadGeneration) ? WixBundleMsiPackageAttributes.SuppressLooseFilePayloadGeneration : 0;
2094 2077
2095 this.Core.AddTuple(new WixBundleMsiPackageTuple(sourceLineNumbers, id) 2078 this.Core.AddTuple(new WixBundleMsiPackageTuple(sourceLineNumbers, id)
2096 { 2079 {
@@ -2458,9 +2441,9 @@ namespace WixToolset.Core
2458 2441
2459 if (!this.Core.EncounteredError) 2442 if (!this.Core.EncounteredError)
2460 { 2443 {
2461 var tuple = new WixBundleMsiPropertyTuple(sourceLineNumbers) 2444 var tuple = new WixBundleMsiPropertyTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, packageId, name))
2462 { 2445 {
2463 WixBundlePackageRef = packageId, 2446 PackageRef = packageId,
2464 Name = name, 2447 Name = name,
2465 Value = value 2448 Value = value
2466 }; 2449 };
@@ -2514,10 +2497,10 @@ namespace WixToolset.Core
2514 2497
2515 if (!this.Core.EncounteredError) 2498 if (!this.Core.EncounteredError)
2516 { 2499 {
2517 this.Core.AddTuple(new WixBundleSlipstreamMspTuple(sourceLineNumbers) 2500 this.Core.AddTuple(new WixBundleSlipstreamMspTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, packageId, id))
2518 { 2501 {
2519 WixBundlePackageRef = packageId, 2502 TargetPackageRef = packageId,
2520 MspWixBundlePackageRef = id 2503 MspPackageRef = id
2521 }); 2504 });
2522 } 2505 }
2523 } 2506 }
diff --git a/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs b/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs
index 6cc91487..0bdecf7a 100644
--- a/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs
+++ b/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs
@@ -1,4 +1,4 @@
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. 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 2
3namespace WixToolset.Core.ExtensibilityServices 3namespace WixToolset.Core.ExtensibilityServices
4{ 4{
@@ -40,6 +40,15 @@ namespace WixToolset.Core.ExtensibilityServices
40 return Uuid.NewUuid(namespaceGuid, value).ToString("B").ToUpperInvariant(); 40 return Uuid.NewUuid(namespaceGuid, value).ToString("B").ToUpperInvariant();
41 } 41 }
42 42
43 public IResolvedDirectory CreateResolvedDirectory(string directoryParent, string name)
44 {
45 return new ResolvedDirectory
46 {
47 DirectoryParent = directoryParent,
48 Name = name
49 };
50 }
51
43 public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null) 52 public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null)
44 { 53 {
45 return new TrackedFile(path, type, sourceLineNumbers); 54 return new TrackedFile(path, type, sourceLineNumbers);
diff --git a/src/WixToolset.Core/ExtensibilityServices/PathResolver.cs b/src/WixToolset.Core/ExtensibilityServices/PathResolver.cs
new file mode 100644
index 00000000..15cd4fc9
--- /dev/null
+++ b/src/WixToolset.Core/ExtensibilityServices/PathResolver.cs
@@ -0,0 +1,91 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Core.ExtensibilityServices
4{
5 using System;
6 using System.Collections.Generic;
7 using System.IO;
8 using WixToolset.Data;
9 using WixToolset.Data.WindowsInstaller;
10 using WixToolset.Extensibility.Data;
11 using WixToolset.Extensibility.Services;
12
13 internal class PathResolver : IPathResolver
14 {
15 public string GetDirectoryPath(Dictionary<string, IResolvedDirectory> directories, Dictionary<string, string> componentIdGenSeeds, string directory, bool canonicalize)
16 {
17 if (!directories.TryGetValue(directory, out var resolvedDirectory))
18 {
19 throw new WixException(ErrorMessages.ExpectedDirectory(directory));
20 }
21
22 if (null == resolvedDirectory.Path)
23 {
24 if (null != componentIdGenSeeds && componentIdGenSeeds.ContainsKey(directory))
25 {
26 resolvedDirectory.Path = componentIdGenSeeds[directory];
27 }
28 else if (canonicalize && WindowsInstallerStandard.IsStandardDirectory(directory))
29 {
30 // when canonicalization is on, standard directories are treated equally
31 resolvedDirectory.Path = directory;
32 }
33 else
34 {
35 string name = resolvedDirectory.Name;
36
37 if (canonicalize)
38 {
39 name = name?.ToLowerInvariant();
40 }
41
42 if (String.IsNullOrEmpty(resolvedDirectory.DirectoryParent))
43 {
44 resolvedDirectory.Path = name;
45 }
46 else
47 {
48 var parentPath = this.GetDirectoryPath(directories, componentIdGenSeeds, resolvedDirectory.DirectoryParent, canonicalize);
49
50 if (null != resolvedDirectory.Name)
51 {
52 resolvedDirectory.Path = Path.Combine(parentPath, name);
53 }
54 else
55 {
56 resolvedDirectory.Path = parentPath;
57 }
58 }
59 }
60 }
61
62 return resolvedDirectory.Path;
63 }
64
65 public string GetFileSourcePath(Dictionary<string, IResolvedDirectory> directories, string directoryId, string fileName, bool compressed, bool useLongName)
66 {
67 var fileSourcePath = Common.GetName(fileName, true, useLongName);
68
69 if (compressed)
70 {
71 // Use just the file name of the file since all uncompressed files must appear
72 // in the root of the image in a compressed package.
73 }
74 else
75 {
76 // Get the relative path of where we want the file to be layed out as specified
77 // in the Directory table.
78 var directoryPath = this.GetDirectoryPath(directories, null, directoryId, false);
79 fileSourcePath = Path.Combine(directoryPath, fileSourcePath);
80 }
81
82 // Strip off "SourceDir" if it's still on there.
83 if (fileSourcePath.StartsWith("SourceDir\\", StringComparison.Ordinal))
84 {
85 fileSourcePath = fileSourcePath.Substring(10);
86 }
87
88 return fileSourcePath;
89 }
90 }
91}
diff --git a/src/WixToolset.Core/ExtensibilityServices/ResolvedDirectory.cs b/src/WixToolset.Core/ExtensibilityServices/ResolvedDirectory.cs
new file mode 100644
index 00000000..cc8acfdd
--- /dev/null
+++ b/src/WixToolset.Core/ExtensibilityServices/ResolvedDirectory.cs
@@ -0,0 +1,15 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Core.ExtensibilityServices
4{
5 using WixToolset.Extensibility.Data;
6
7 internal class ResolvedDirectory : IResolvedDirectory
8 {
9 public string DirectoryParent { get; set; }
10
11 public string Name { get; set; }
12
13 public string Path { get; set; }
14 }
15}
diff --git a/src/WixToolset.Core/ExtensibilityServices/WindowsInstallerBackendHelper.cs b/src/WixToolset.Core/ExtensibilityServices/WindowsInstallerBackendHelper.cs
index 6e0ffce6..26982ad6 100644
--- a/src/WixToolset.Core/ExtensibilityServices/WindowsInstallerBackendHelper.cs
+++ b/src/WixToolset.Core/ExtensibilityServices/WindowsInstallerBackendHelper.cs
@@ -1,8 +1,7 @@
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. 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 2
3namespace WixToolset.Core.ExtensibilityServices 3namespace WixToolset.Core.ExtensibilityServices
4{ 4{
5 using System;
6 using System.Linq; 5 using System.Linq;
7 using WixToolset.Data; 6 using WixToolset.Data;
8 using WixToolset.Data.WindowsInstaller; 7 using WixToolset.Data.WindowsInstaller;
@@ -10,14 +9,9 @@ namespace WixToolset.Core.ExtensibilityServices
10 9
11 internal class WindowsInstallerBackendHelper : IWindowsInstallerBackendHelper 10 internal class WindowsInstallerBackendHelper : IWindowsInstallerBackendHelper
12 { 11 {
13 public WindowsInstallerBackendHelper(IServiceProvider serviceProvider) 12 public bool TryAddTupleToOutputMatchingTableDefinitions(IntermediateTuple tuple, Output output, TableDefinition[] tableDefinitions) => this.TryAddTupleToOutputMatchingTableDefinitions(tuple, output, tableDefinitions, false);
14 {
15 this.ServiceProvider = serviceProvider;
16 }
17 13
18 private IServiceProvider ServiceProvider { get; } 14 public bool TryAddTupleToOutputMatchingTableDefinitions(IntermediateTuple tuple, Output output, TableDefinition[] tableDefinitions, bool columnZeroIsId)
19
20 public bool TryAddTupleToOutputMatchingTableDefinitions(IntermediateTuple tuple, Output output, TableDefinition[] tableDefinitions)
21 { 15 {
22 var tableDefinition = tableDefinitions.FirstOrDefault(t => t.Name == tuple.Definition.Name); 16 var tableDefinition = tableDefinitions.FirstOrDefault(t => t.Name == tuple.Definition.Name);
23 17
@@ -28,6 +22,14 @@ namespace WixToolset.Core.ExtensibilityServices
28 22
29 var table = output.EnsureTable(tableDefinition); 23 var table = output.EnsureTable(tableDefinition);
30 var row = table.CreateRow(tuple.SourceLineNumbers); 24 var row = table.CreateRow(tuple.SourceLineNumbers);
25 var rowOffset = 0;
26
27 if (columnZeroIsId)
28 {
29 row[0] = tuple.Id.Id;
30 rowOffset = 1;
31 }
32
31 for (var i = 0; i < tuple.Fields.Length; ++i) 33 for (var i = 0; i < tuple.Fields.Length; ++i)
32 { 34 {
33 if (i < tableDefinition.Columns.Length) 35 if (i < tableDefinition.Columns.Length)
@@ -36,13 +38,13 @@ namespace WixToolset.Core.ExtensibilityServices
36 38
37 switch (column.Type) 39 switch (column.Type)
38 { 40 {
39 case ColumnType.Number: 41 case ColumnType.Number:
40 row[i] = tuple.AsNumber(i); 42 row[i + rowOffset] = column.Nullable ? tuple.AsNullableNumber(i) : tuple.AsNumber(i);
41 break; 43 break;
42 44
43 default: 45 default:
44 row[i] = tuple.AsString(i); 46 row[i + rowOffset] = tuple.AsString(i);
45 break; 47 break;
46 } 48 }
47 } 49 }
48 } 50 }
diff --git a/src/WixToolset.Core/Link/WixGroupingOrdering.cs b/src/WixToolset.Core/Link/WixGroupingOrdering.cs
index 9080775e..563cd565 100644
--- a/src/WixToolset.Core/Link/WixGroupingOrdering.cs
+++ b/src/WixToolset.Core/Link/WixGroupingOrdering.cs
@@ -12,19 +12,19 @@ namespace WixToolset.Core.Link
12 using WixToolset.Data; 12 using WixToolset.Data;
13 using WixToolset.Data.Tuples; 13 using WixToolset.Data.Tuples;
14 using WixToolset.Extensibility.Services; 14 using WixToolset.Extensibility.Services;
15 using WixToolset.Data.Burn;
15 16
16 /// <summary> 17 /// <summary>
17 /// Grouping and Ordering class of the WiX toolset. 18 /// Grouping and Ordering class of the WiX toolset.
18 /// </summary> 19 /// </summary>
19 internal class WixGroupingOrdering 20 internal class WixGroupingOrdering
20 { 21 {
21 private readonly IMessaging messageHandler; 22 private readonly IMessaging Messaging;
22 private List<string> groupTypes; 23 private List<string> groupTypes;
23 private List<string> itemTypes; 24 private List<string> itemTypes;
24 private ItemCollection items; 25 private ItemCollection items;
25 private readonly List<int> rowsUsed; 26 private readonly List<int> rowsUsed;
26 private bool loaded; 27 private bool loaded;
27 private bool encounteredError;
28 28
29 /// <summary> 29 /// <summary>
30 /// Creates a WixGroupingOrdering object. 30 /// Creates a WixGroupingOrdering object.
@@ -36,11 +36,10 @@ namespace WixToolset.Core.Link
36 public WixGroupingOrdering(IntermediateSection entrySections, IMessaging messageHandler) 36 public WixGroupingOrdering(IntermediateSection entrySections, IMessaging messageHandler)
37 { 37 {
38 this.EntrySection = entrySections; 38 this.EntrySection = entrySections;
39 this.messageHandler = messageHandler; 39 this.Messaging = messageHandler;
40 40
41 this.rowsUsed = new List<int>(); 41 this.rowsUsed = new List<int>();
42 this.loaded = false; 42 this.loaded = false;
43 this.encounteredError = false;
44 } 43 }
45 44
46 private IntermediateSection EntrySection { get; } 45 private IntermediateSection EntrySection { get; }
@@ -71,7 +70,7 @@ namespace WixToolset.Core.Link
71 Debug.Assert(this.groupTypes.Contains(parentTypeString)); 70 Debug.Assert(this.groupTypes.Contains(parentTypeString));
72 71
73 this.CreateOrderedList(parentTypeString, parentId, out var orderedItems); 72 this.CreateOrderedList(parentTypeString, parentId, out var orderedItems);
74 if (this.encounteredError) 73 if (this.Messaging.EncounteredError)
75 { 74 {
76 return; 75 return;
77 } 76 }
@@ -95,7 +94,7 @@ namespace WixToolset.Core.Link
95 Debug.Assert(this.groupTypes.Contains(parentTypeString)); 94 Debug.Assert(this.groupTypes.Contains(parentTypeString));
96 95
97 this.LoadFlattenOrderGroups(); 96 this.LoadFlattenOrderGroups();
98 if (this.encounteredError) 97 if (this.Messaging.EncounteredError)
99 { 98 {
100 return; 99 return;
101 } 100 }
@@ -127,14 +126,14 @@ namespace WixToolset.Core.Link
127 orderedItems = null; 126 orderedItems = null;
128 127
129 this.LoadFlattenOrderGroups(); 128 this.LoadFlattenOrderGroups();
130 if (this.encounteredError) 129 if (this.Messaging.EncounteredError)
131 { 130 {
132 return; 131 return;
133 } 132 }
134 133
135 if (!this.items.TryGetValue(parentType, parentId, out var parentItem)) 134 if (!this.items.TryGetValue(parentType, parentId, out var parentItem))
136 { 135 {
137 this.messageHandler.Write(ErrorMessages.IdentifierNotFound(parentType, parentId)); 136 this.Messaging.Write(ErrorMessages.IdentifierNotFound(parentType, parentId));
138 return; 137 return;
139 } 138 }
140 139
@@ -216,7 +215,7 @@ namespace WixToolset.Core.Link
216 // dependencies. Group references, however, we can check directly. 215 // dependencies. Group references, however, we can check directly.
217 this.FindCircularGroupReferences(); 216 this.FindCircularGroupReferences();
218 217
219 if (!this.encounteredError) 218 if (!this.Messaging.EncounteredError)
220 { 219 {
221 this.FlattenGroups(); 220 this.FlattenGroups();
222 this.FlattenOrdering(); 221 this.FlattenOrdering();
@@ -304,7 +303,7 @@ namespace WixToolset.Core.Link
304 if (this.FindCircularGroupReference(item, item, itemsSeen, out circularReference)) 303 if (this.FindCircularGroupReference(item, item, itemsSeen, out circularReference))
305 { 304 {
306 itemsInKnownLoops.Add(itemsSeen); 305 itemsInKnownLoops.Add(itemsSeen);
307 this.messageHandler.Write(ErrorMessages.ReferenceLoopDetected(item.Row.SourceLineNumbers, circularReference)); 306 this.Messaging.Write(ErrorMessages.ReferenceLoopDetected(item.Row.SourceLineNumbers, circularReference));
308 } 307 }
309 } 308 }
310 } 309 }
@@ -376,12 +375,12 @@ namespace WixToolset.Core.Link
376 375
377 if (!this.items.TryGetValue(rowItemType, rowItemName, out var item)) 376 if (!this.items.TryGetValue(rowItemType, rowItemName, out var item))
378 { 377 {
379 this.messageHandler.Write(ErrorMessages.IdentifierNotFound(rowItemType, rowItemName)); 378 this.Messaging.Write(ErrorMessages.IdentifierNotFound(rowItemType, rowItemName));
380 } 379 }
381 380
382 if (!this.items.TryGetValue(rowDependsOnType, rowDependsOnName, out var dependsOn)) 381 if (!this.items.TryGetValue(rowDependsOnType, rowDependsOnName, out var dependsOn))
383 { 382 {
384 this.messageHandler.Write(ErrorMessages.IdentifierNotFound(rowDependsOnType, rowDependsOnName)); 383 this.Messaging.Write(ErrorMessages.IdentifierNotFound(rowDependsOnType, rowDependsOnName));
385 } 384 }
386 385
387 if (null == item || null == dependsOn) 386 if (null == item || null == dependsOn)
@@ -389,7 +388,7 @@ namespace WixToolset.Core.Link
389 continue; 388 continue;
390 } 389 }
391 390
392 item.AddAfter(dependsOn, this.messageHandler); 391 item.AddAfter(dependsOn, this.Messaging);
393 } 392 }
394 } 393 }
395 394
@@ -404,12 +403,12 @@ namespace WixToolset.Core.Link
404 // ordering. 403 // ordering.
405 foreach (Item item in this.items) 404 foreach (Item item in this.items)
406 { 405 {
407 item.PropagateAfterToChildItems(this.messageHandler); 406 item.PropagateAfterToChildItems(this.Messaging);
408 } 407 }
409 408
410 foreach (Item item in this.items) 409 foreach (Item item in this.items)
411 { 410 {
412 item.FlattenAfters(this.messageHandler); 411 item.FlattenAfters(this.Messaging);
413 } 412 }
414 } 413 }
415 414
@@ -668,7 +667,7 @@ namespace WixToolset.Core.Link
668 { 667 {
669 if (String.Equals(nameof(ComplexReferenceChildType.Package), this.Type, StringComparison.Ordinal) || 668 if (String.Equals(nameof(ComplexReferenceChildType.Package), this.Type, StringComparison.Ordinal) ||
670 (String.Equals(nameof(ComplexReferenceParentType.Container), this.Type, StringComparison.Ordinal) && 669 (String.Equals(nameof(ComplexReferenceParentType.Container), this.Type, StringComparison.Ordinal) &&
671 !String.Equals(Compiler.BurnUXContainerId.Id, this.Id, StringComparison.Ordinal))) 670 !String.Equals(BurnConstants.BurnUXContainerName, this.Id, StringComparison.Ordinal)))
672 { 671 {
673 return false; 672 return false;
674 } 673 }
diff --git a/src/WixToolset.Core/WixToolsetServiceProvider.cs b/src/WixToolset.Core/WixToolsetServiceProvider.cs
index 267e4524..c7d6ff1d 100644
--- a/src/WixToolset.Core/WixToolsetServiceProvider.cs
+++ b/src/WixToolset.Core/WixToolsetServiceProvider.cs
@@ -24,7 +24,8 @@ namespace WixToolset.Core
24 this.AddService((provider, singletons) => AddSingleton<IParseHelper>(singletons, new ParseHelper(provider))); 24 this.AddService((provider, singletons) => AddSingleton<IParseHelper>(singletons, new ParseHelper(provider)));
25 this.AddService((provider, singletons) => AddSingleton<IPreprocessHelper>(singletons, new PreprocessHelper(provider))); 25 this.AddService((provider, singletons) => AddSingleton<IPreprocessHelper>(singletons, new PreprocessHelper(provider)));
26 this.AddService((provider, singletons) => AddSingleton<IBackendHelper>(singletons, new BackendHelper(provider))); 26 this.AddService((provider, singletons) => AddSingleton<IBackendHelper>(singletons, new BackendHelper(provider)));
27 this.AddService((provider, singletons) => AddSingleton<IWindowsInstallerBackendHelper>(singletons, new WindowsInstallerBackendHelper(provider))); 27 this.AddService((provider, singletons) => AddSingleton<IPathResolver>(singletons, new PathResolver()));
28 this.AddService((provider, singletons) => AddSingleton<IWindowsInstallerBackendHelper>(singletons, new WindowsInstallerBackendHelper()));
28 29
29 // Transients. 30 // Transients.
30 this.AddService<ICommandLineArguments>((provider, singletons) => new CommandLineArguments(provider)); 31 this.AddService<ICommandLineArguments>((provider, singletons) => new CommandLineArguments(provider));
@@ -47,6 +48,7 @@ namespace WixToolset.Core
47 this.AddService<IDecompileResult>((provider, singletons) => new DecompileResult()); 48 this.AddService<IDecompileResult>((provider, singletons) => new DecompileResult());
48 this.AddService<IIncludedFile>((provider, singletons) => new IncludedFile()); 49 this.AddService<IIncludedFile>((provider, singletons) => new IncludedFile());
49 this.AddService<IPreprocessResult>((provider, singletons) => new PreprocessResult()); 50 this.AddService<IPreprocessResult>((provider, singletons) => new PreprocessResult());
51 this.AddService<IResolvedDirectory>((provider, singletons) => new ResolvedDirectory());
50 this.AddService<IResolveFileResult>((provider, singletons) => new ResolveFileResult()); 52 this.AddService<IResolveFileResult>((provider, singletons) => new ResolveFileResult());
51 this.AddService<IResolveResult>((provider, singletons) => new ResolveResult()); 53 this.AddService<IResolveResult>((provider, singletons) => new ResolveResult());
52 this.AddService<IResolvedCabinet>((provider, singletons) => new ResolvedCabinet()); 54 this.AddService<IResolvedCabinet>((provider, singletons) => new ResolvedCabinet());