aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-03-23 01:21:51 -0700
committerRob Mensching <rob@firegiant.com>2021-03-23 01:30:11 -0700
commit977b748b499e02f7e5226416b1cf5cfcf3842129 (patch)
tree95c7c01847d80bb40341cc41f6e0ee9922949802 /src
parent460df3a34b4cdd8d111ff5d627fbd4bce00d806f (diff)
downloadwix-977b748b499e02f7e5226416b1cf5cfcf3842129.tar.gz
wix-977b748b499e02f7e5226416b1cf5cfcf3842129.tar.bz2
wix-977b748b499e02f7e5226416b1cf5cfcf3842129.zip
Allow payloads to be shared across packages in a Bundle
Fixes wixtoolset/issues#6370
Diffstat (limited to 'src')
-rw-r--r--src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs81
-rw-r--r--src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs54
-rw-r--r--src/WixToolset.Core.Burn/Bundles/CreateBundleExtensionManifestCommand.cs8
-rw-r--r--src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs10
-rw-r--r--src/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs3
-rw-r--r--src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs32
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs10
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/TestData/SharedPayloadsBetweenPackages/SharedPayloadsBetweenPackages.wxs2
8 files changed, 129 insertions, 71 deletions
diff --git a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
index 7b5a3174..d154fef9 100644
--- a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+++ b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
@@ -63,7 +63,7 @@ namespace WixToolset.Core.Burn
63 63
64 private IEnumerable<IBurnBackendBinderExtension> BackendExtensions { get; } 64 private IEnumerable<IBurnBackendBinderExtension> BackendExtensions { get; }
65 65
66 private Intermediate Output { get; } 66 private Intermediate Output { get; }
67 67
68 private string OutputPath { get; } 68 private string OutputPath { get; }
69 69
@@ -95,7 +95,7 @@ namespace WixToolset.Core.Burn
95 95
96 var wixGroupSymbols = this.GetRequiredSymbols<WixGroupSymbol>(); 96 var wixGroupSymbols = this.GetRequiredSymbols<WixGroupSymbol>();
97 97
98 // Ensure there is one and only one row in the WixBundle table. 98 // Ensure there is one and only one WixBundleSymbol.
99 // The compiler and linker behavior should have colluded to get 99 // The compiler and linker behavior should have colluded to get
100 // this behavior. 100 // this behavior.
101 var bundleSymbol = this.GetSingleSymbol<WixBundleSymbol>(); 101 var bundleSymbol = this.GetSingleSymbol<WixBundleSymbol>();
@@ -104,12 +104,12 @@ namespace WixToolset.Core.Burn
104 104
105 bundleSymbol.Attributes |= WixBundleAttributes.PerMachine; // default to per-machine but the first-per user package wil flip the bundle per-user. 105 bundleSymbol.Attributes |= WixBundleAttributes.PerMachine; // default to per-machine but the first-per user package wil flip the bundle per-user.
106 106
107 // Ensure there is one and only one row in the WixBootstrapperApplicationDll table. 107 // Ensure there is one and only one WixBootstrapperApplicationDllSymbol.
108 // The compiler and linker behavior should have colluded to get 108 // The compiler and linker behavior should have colluded to get
109 // this behavior. 109 // this behavior.
110 var bundleApplicationDllSymbol = this.GetSingleSymbol<WixBootstrapperApplicationDllSymbol>(); 110 var bundleApplicationDllSymbol = this.GetSingleSymbol<WixBootstrapperApplicationDllSymbol>();
111 111
112 // Ensure there is one and only one row in the WixChain table. 112 // Ensure there is one and only one WixChainSymbol.
113 // The compiler and linker behavior should have colluded to get 113 // The compiler and linker behavior should have colluded to get
114 // this behavior. 114 // this behavior.
115 var chainSymbol = this.GetSingleSymbol<WixChainSymbol>(); 115 var chainSymbol = this.GetSingleSymbol<WixChainSymbol>();
@@ -122,10 +122,15 @@ namespace WixToolset.Core.Burn
122 // If there are any fields to resolve later, create the cache to populate during bind. 122 // If there are any fields to resolve later, create the cache to populate during bind.
123 var variableCache = this.DelayedFields.Any() ? new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase) : null; 123 var variableCache = this.DelayedFields.Any() ? new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase) : null;
124 124
125 var orderSearchesCommand = new OrderSearchesCommand(this.Messaging, section); 125 IEnumerable<ISearchFacade> orderedSearches;
126 orderSearchesCommand.Execute(); 126 IDictionary<string, IEnumerable<IntermediateSymbol>> extensionSearchSymbolsById;
127 var orderedSearches = orderSearchesCommand.OrderedSearchFacades; 127 {
128 var extensionSearchSymbolsById = orderSearchesCommand.ExtensionSearchSymbolsByExtensionId; 128 var orderSearchesCommand = new OrderSearchesCommand(this.Messaging, section);
129 orderSearchesCommand.Execute();
130
131 orderedSearches = orderSearchesCommand.OrderedSearchFacades;
132 extensionSearchSymbolsById = orderSearchesCommand.ExtensionSearchSymbolsByExtensionId;
133 }
129 134
130 // Extract files that come from binary .wixlibs and WixExtensions (this does not extract files from merge modules). 135 // Extract files that come from binary .wixlibs and WixExtensions (this does not extract files from merge modules).
131 { 136 {
@@ -136,8 +141,9 @@ namespace WixToolset.Core.Burn
136 141
137 // Get the explicit payloads. 142 // Get the explicit payloads.
138 var payloadSymbols = section.Symbols.OfType<WixBundlePayloadSymbol>().ToDictionary(t => t.Id.Id); 143 var payloadSymbols = section.Symbols.OfType<WixBundlePayloadSymbol>().ToDictionary(t => t.Id.Id);
144 var packagesPayloads = RecalculatePackagesPayloads(payloadSymbols, wixGroupSymbols);
139 145
140 // Update explicitly authored payloads with their parent package and container (as appropriate) 146 // Update explicitly authored payloads with their parent container
141 // to make it easier to gather the payloads later. 147 // to make it easier to gather the payloads later.
142 foreach (var groupSymbol in wixGroupSymbols) 148 foreach (var groupSymbol in wixGroupSymbols)
143 { 149 {
@@ -145,14 +151,10 @@ namespace WixToolset.Core.Burn
145 { 151 {
146 var payloadSymbol = payloadSymbols[groupSymbol.ChildId]; 152 var payloadSymbol = payloadSymbols[groupSymbol.ChildId];
147 153
148 if (ComplexReferenceParentType.Package == groupSymbol.ParentType) 154 if (ComplexReferenceParentType.Container == groupSymbol.ParentType)
149 { 155 {
150 Debug.Assert(String.IsNullOrEmpty(payloadSymbol.PackageRef)); 156 // TODO: v3 didn't warn if we overwrote the payload's container.
151 payloadSymbol.PackageRef = groupSymbol.ParentId; 157 // Should we warn now?
152 }
153 else if (ComplexReferenceParentType.Container == groupSymbol.ParentType)
154 {
155 Debug.Assert(String.IsNullOrEmpty(payloadSymbol.ContainerRef));
156 payloadSymbol.ContainerRef = groupSymbol.ParentId; 158 payloadSymbol.ContainerRef = groupSymbol.ParentId;
157 } 159 }
158 else if (ComplexReferenceParentType.Layout == groupSymbol.ParentType) 160 else if (ComplexReferenceParentType.Layout == groupSymbol.ParentType)
@@ -167,7 +169,7 @@ namespace WixToolset.Core.Burn
167 // Process the explicitly authored payloads. 169 // Process the explicitly authored payloads.
168 ISet<string> processedPayloads; 170 ISet<string> processedPayloads;
169 { 171 {
170 var command = new ProcessPayloadsCommand(this.ServiceProvider, this.BackendHelper, this.PayloadHarvester, payloadSymbols.Values, bundleSymbol.DefaultPackagingType, layoutDirectory); 172 var command = new ProcessPayloadsCommand(this.BackendHelper, this.PayloadHarvester, payloadSymbols.Values, bundleSymbol.DefaultPackagingType, layoutDirectory);
171 command.Execute(); 173 command.Execute();
172 174
173 fileTransfers.AddRange(command.FileTransfers); 175 fileTransfers.AddRange(command.FileTransfers);
@@ -204,7 +206,7 @@ namespace WixToolset.Core.Burn
204 206
205 case WixBundlePackageType.Msi: 207 case WixBundlePackageType.Msi:
206 { 208 {
207 var command = new ProcessMsiPackageCommand(this.ServiceProvider, this.BackendExtensions, section, facade, payloadSymbols); 209 var command = new ProcessMsiPackageCommand(this.ServiceProvider, this.BackendExtensions, section, facade, packagesPayloads[facade.PackageId]);
208 command.Execute(); 210 command.Execute();
209 211
210 if (null != variableCache) 212 if (null != variableCache)
@@ -249,12 +251,13 @@ namespace WixToolset.Core.Burn
249 // Reindex the payloads now that all the payloads (minus the manifest payloads that will be created later) 251 // Reindex the payloads now that all the payloads (minus the manifest payloads that will be created later)
250 // are present. 252 // are present.
251 payloadSymbols = section.Symbols.OfType<WixBundlePayloadSymbol>().ToDictionary(t => t.Id.Id); 253 payloadSymbols = section.Symbols.OfType<WixBundlePayloadSymbol>().ToDictionary(t => t.Id.Id);
254 packagesPayloads = RecalculatePackagesPayloads(payloadSymbols, wixGroupSymbols);
252 255
253 // Process the payloads that were added by processing the packages. 256 // Process the payloads that were added by processing the packages.
254 { 257 {
255 var toProcess = payloadSymbols.Values.Where(r => !processedPayloads.Contains(r.Id.Id)).ToList(); 258 var toProcess = payloadSymbols.Values.Where(r => !processedPayloads.Contains(r.Id.Id)).ToList();
256 259
257 var command = new ProcessPayloadsCommand(this.ServiceProvider, this.BackendHelper, this.PayloadHarvester, toProcess, bundleSymbol.DefaultPackagingType, layoutDirectory); 260 var command = new ProcessPayloadsCommand(this.BackendHelper, this.PayloadHarvester, toProcess, bundleSymbol.DefaultPackagingType, layoutDirectory);
258 command.Execute(); 261 command.Execute();
259 262
260 fileTransfers.AddRange(command.FileTransfers); 263 fileTransfers.AddRange(command.FileTransfers);
@@ -265,15 +268,13 @@ namespace WixToolset.Core.Burn
265 268
266 // Set the package metadata from the payloads now that we have the complete payload information. 269 // Set the package metadata from the payloads now that we have the complete payload information.
267 { 270 {
268 var payloadsByPackageId = payloadSymbols.Values.ToLookup(p => p.PackageRef);
269
270 foreach (var facade in facades.Values) 271 foreach (var facade in facades.Values)
271 { 272 {
272 facade.PackageSymbol.Size = 0; 273 facade.PackageSymbol.Size = 0;
273 274
274 var packagePayloads = payloadsByPackageId[facade.PackageId]; 275 var packagePayloads = packagesPayloads[facade.PackageId];
275 276
276 foreach (var payload in packagePayloads) 277 foreach (var payload in packagePayloads.Values)
277 { 278 {
278 facade.PackageSymbol.Size += payload.FileSize.Value; 279 facade.PackageSymbol.Size += payload.FileSize.Value;
279 } 280 }
@@ -415,7 +416,7 @@ namespace WixToolset.Core.Burn
415 // Generate the core-defined BA manifest tables... 416 // Generate the core-defined BA manifest tables...
416 string baManifestPath; 417 string baManifestPath;
417 { 418 {
418 var command = new CreateBootstrapperApplicationManifestCommand(section, bundleSymbol, orderedFacades, uxPayloadIndex, payloadSymbols, this.IntermediateFolder, this.InternalBurnBackendHelper); 419 var command = new CreateBootstrapperApplicationManifestCommand(section, bundleSymbol, orderedFacades, uxPayloadIndex, packagesPayloads, this.IntermediateFolder, this.InternalBurnBackendHelper);
419 command.Execute(); 420 command.Execute();
420 421
421 var baManifestPayload = command.BootstrapperApplicationManifestPayloadRow; 422 var baManifestPayload = command.BootstrapperApplicationManifestPayloadRow;
@@ -462,7 +463,7 @@ namespace WixToolset.Core.Burn
462 { 463 {
463 var executableName = Path.GetFileName(this.OutputPath); 464 var executableName = Path.GetFileName(this.OutputPath);
464 465
465 var command = new CreateBurnManifestCommand(this.Messaging, this.BackendExtensions, executableName, section, bundleSymbol, containers, chainSymbol, orderedFacades, boundaries, uxPayloads, payloadSymbols, orderedSearches, this.IntermediateFolder); 466 var command = new CreateBurnManifestCommand(this.Messaging, this.BackendExtensions, executableName, section, bundleSymbol, containers, chainSymbol, orderedFacades, boundaries, uxPayloads, payloadSymbols, packagesPayloads, orderedSearches, this.IntermediateFolder);
466 command.Execute(); 467 command.Execute();
467 468
468 manifestPath = command.OutputPath; 469 manifestPath = command.OutputPath;
@@ -580,7 +581,7 @@ namespace WixToolset.Core.Burn
580 581
581 if (0 == symbols.Count) 582 if (0 == symbols.Count)
582 { 583 {
583 throw new WixException(ErrorMessages.MissingBundleInformation(nameof(T))); 584 this.Messaging.Write(ErrorMessages.MissingBundleInformation(nameof(T)));
584 } 585 }
585 586
586 return symbols; 587 return symbols;
@@ -592,10 +593,36 @@ namespace WixToolset.Core.Burn
592 593
593 if (1 != symbols.Count) 594 if (1 != symbols.Count)
594 { 595 {
595 throw new WixException(ErrorMessages.MissingBundleInformation(nameof(T))); 596 this.Messaging.Write(ErrorMessages.MissingBundleInformation(nameof(T)));
596 } 597 }
597 598
598 return symbols[0]; 599 return symbols[0];
599 } 600 }
601
602 private static Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> RecalculatePackagesPayloads(Dictionary<string, WixBundlePayloadSymbol> payloadSymbols, IEnumerable<WixGroupSymbol> wixGroupSymbols)
603 {
604 var packagesPayloads = new Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>>();
605
606 foreach (var groupSymbol in wixGroupSymbols)
607 {
608 if (ComplexReferenceChildType.Payload == groupSymbol.ChildType)
609 {
610 var payloadSymbol = payloadSymbols[groupSymbol.ChildId];
611
612 if (ComplexReferenceParentType.Package == groupSymbol.ParentType)
613 {
614 if (!packagesPayloads.TryGetValue(groupSymbol.ParentId, out var packagePayloadsById))
615 {
616 packagePayloadsById = new Dictionary<string, WixBundlePayloadSymbol>();
617 packagesPayloads.Add(groupSymbol.ParentId, packagePayloadsById);
618 }
619
620 packagePayloadsById.Add(payloadSymbol.Id.Id, payloadSymbol);
621 }
622 }
623 }
624
625 return packagesPayloads;
626 }
600 } 627 }
601} 628}
diff --git a/src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs b/src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
index 63a168a0..1fdd76da 100644
--- a/src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
@@ -15,13 +15,13 @@ namespace WixToolset.Core.Burn.Bundles
15 15
16 internal class CreateBootstrapperApplicationManifestCommand 16 internal class CreateBootstrapperApplicationManifestCommand
17 { 17 {
18 public CreateBootstrapperApplicationManifestCommand(IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<PackageFacade> chainPackages, int lastUXPayloadIndex, Dictionary<string, WixBundlePayloadSymbol> payloadSymbols, string intermediateFolder, IInternalBurnBackendHelper internalBurnBackendHelper) 18 public CreateBootstrapperApplicationManifestCommand(IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<PackageFacade> chainPackages, int lastUXPayloadIndex, Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> packagesPayloads, string intermediateFolder, IInternalBurnBackendHelper internalBurnBackendHelper)
19 { 19 {
20 this.Section = section; 20 this.Section = section;
21 this.BundleSymbol = bundleSymbol; 21 this.BundleSymbol = bundleSymbol;
22 this.ChainPackages = chainPackages; 22 this.ChainPackages = chainPackages;
23 this.LastUXPayloadIndex = lastUXPayloadIndex; 23 this.LastUXPayloadIndex = lastUXPayloadIndex;
24 this.Payloads = payloadSymbols; 24 this.PackagesPayloads = packagesPayloads;
25 this.IntermediateFolder = intermediateFolder; 25 this.IntermediateFolder = intermediateFolder;
26 this.InternalBurnBackendHelper = internalBurnBackendHelper; 26 this.InternalBurnBackendHelper = internalBurnBackendHelper;
27 } 27 }
@@ -36,7 +36,7 @@ namespace WixToolset.Core.Burn.Bundles
36 36
37 private int LastUXPayloadIndex { get; } 37 private int LastUXPayloadIndex { get; }
38 38
39 private Dictionary<string, WixBundlePayloadSymbol> Payloads { get; } 39 private Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> PackagesPayloads { get; }
40 40
41 private string IntermediateFolder { get; } 41 private string IntermediateFolder { get; }
42 42
@@ -98,7 +98,12 @@ namespace WixToolset.Core.Burn.Bundles
98 { 98 {
99 foreach (var package in this.ChainPackages) 99 foreach (var package in this.ChainPackages)
100 { 100 {
101 var packagePayload = this.Payloads[package.PackageSymbol.PayloadRef]; 101 if (!this.PackagesPayloads.TryGetValue(package.PackageId, out var payloads))
102 {
103 continue;
104 }
105
106 var packagePayload = payloads[package.PackageSymbol.PayloadRef];
102 107
103 var size = package.PackageSymbol.Size.ToString(CultureInfo.InvariantCulture); 108 var size = package.PackageSymbol.Size.ToString(CultureInfo.InvariantCulture);
104 109
@@ -212,33 +217,36 @@ namespace WixToolset.Core.Burn.Bundles
212 private void WritePayloadInfo(XmlTextWriter writer) 217 private void WritePayloadInfo(XmlTextWriter writer)
213 { 218 {
214 // TODO: check v3 - should this be only include package payloads or include all non-UX container payloads? 219 // TODO: check v3 - should this be only include package payloads or include all non-UX container payloads?
215 var payloadSymbols = this.Section.Symbols.OfType<WixBundlePayloadSymbol>() 220 foreach (var kvp in this.PackagesPayloads.OrderBy(kvp => kvp.Key, StringComparer.Ordinal))
216 .Where(p => !String.IsNullOrEmpty(p.PackageRef));
217
218 foreach (var payloadSymbol in payloadSymbols)
219 { 221 {
220 writer.WriteStartElement("WixPayloadProperties"); 222 var packageId = kvp.Key;
223 var payloadsById = kvp.Value;
221 224
222 writer.WriteAttributeString("Payload", payloadSymbol.Id.Id); 225 foreach (var payloadSymbol in payloadsById.Values.OrderBy(p => p.Id.Id, StringComparer.Ordinal))
226 {
227 writer.WriteStartElement("WixPayloadProperties");
223 228
224 writer.WriteAttributeString("Package", payloadSymbol.PackageRef); 229 writer.WriteAttributeString("Package", packageId);
225 230
226 if (!String.IsNullOrEmpty(payloadSymbol.ContainerRef)) 231 writer.WriteAttributeString("Payload", payloadSymbol.Id.Id);
227 { 232
228 writer.WriteAttributeString("Container", payloadSymbol.ContainerRef); 233 if (!String.IsNullOrEmpty(payloadSymbol.ContainerRef))
229 } 234 {
235 writer.WriteAttributeString("Container", payloadSymbol.ContainerRef);
236 }
230 237
231 writer.WriteAttributeString("Name", payloadSymbol.Name); 238 writer.WriteAttributeString("Name", payloadSymbol.Name);
232 writer.WriteAttributeString("Size", payloadSymbol.FileSize.Value.ToString(CultureInfo.InvariantCulture)); 239 writer.WriteAttributeString("Size", payloadSymbol.FileSize.Value.ToString(CultureInfo.InvariantCulture));
233 240
234 if (!String.IsNullOrEmpty(payloadSymbol.DownloadUrl)) 241 if (!String.IsNullOrEmpty(payloadSymbol.DownloadUrl))
235 { 242 {
236 writer.WriteAttributeString("DownloadUrl", payloadSymbol.DownloadUrl); 243 writer.WriteAttributeString("DownloadUrl", payloadSymbol.DownloadUrl);
237 } 244 }
238 245
239 writer.WriteAttributeString("LayoutOnly", payloadSymbol.LayoutOnly ? "yes" : "no"); 246 writer.WriteAttributeString("LayoutOnly", payloadSymbol.LayoutOnly ? "yes" : "no");
240 247
241 writer.WriteEndElement(); 248 writer.WriteEndElement();
249 }
242 } 250 }
243 } 251 }
244 252
diff --git a/src/WixToolset.Core.Burn/Bundles/CreateBundleExtensionManifestCommand.cs b/src/WixToolset.Core.Burn/Bundles/CreateBundleExtensionManifestCommand.cs
index 7b5b9656..e587413e 100644
--- a/src/WixToolset.Core.Burn/Bundles/CreateBundleExtensionManifestCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/CreateBundleExtensionManifestCommand.cs
@@ -68,6 +68,14 @@ namespace WixToolset.Core.Burn.Bundles
68 { 68 {
69 var generatedId = this.InternalBurnBackendHelper.GenerateIdentifier("ux", BurnCommon.BundleExtensionDataFileName); 69 var generatedId = this.InternalBurnBackendHelper.GenerateIdentifier("ux", BurnCommon.BundleExtensionDataFileName);
70 70
71 this.Section.AddSymbol(new WixGroupSymbol(this.BundleSymbol.SourceLineNumbers)
72 {
73 ParentType = ComplexReferenceParentType.Container,
74 ParentId = BurnConstants.BurnUXContainerName,
75 ChildType = ComplexReferenceChildType.Payload,
76 ChildId = generatedId
77 });
78
71 var symbol = this.Section.AddSymbol(new WixBundlePayloadSymbol(this.BundleSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId)) 79 var symbol = this.Section.AddSymbol(new WixBundlePayloadSymbol(this.BundleSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId))
72 { 80 {
73 Name = BurnCommon.BundleExtensionDataFileName, 81 Name = BurnCommon.BundleExtensionDataFileName,
diff --git a/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs b/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
index 1559a646..0c16ea26 100644
--- a/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
@@ -18,7 +18,7 @@ namespace WixToolset.Core.Burn.Bundles
18 18
19 internal class CreateBurnManifestCommand 19 internal class CreateBurnManifestCommand
20 { 20 {
21 public CreateBurnManifestCommand(IMessaging messaging, IEnumerable<IBurnBackendBinderExtension> backendExtensions, string executableName, IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<WixBundleContainerSymbol> containers, WixChainSymbol chainSymbol, IEnumerable<PackageFacade> orderedPackages, IEnumerable<WixBundleRollbackBoundarySymbol> boundaries, IEnumerable<WixBundlePayloadSymbol> uxPayloads, Dictionary<string, WixBundlePayloadSymbol> allPayloadsById, IEnumerable<ISearchFacade> orderedSearches, string intermediateFolder) 21 public CreateBurnManifestCommand(IMessaging messaging, IEnumerable<IBurnBackendBinderExtension> backendExtensions, string executableName, IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<WixBundleContainerSymbol> containers, WixChainSymbol chainSymbol, IEnumerable<PackageFacade> orderedPackages, IEnumerable<WixBundleRollbackBoundarySymbol> boundaries, IEnumerable<WixBundlePayloadSymbol> uxPayloads, Dictionary<string, WixBundlePayloadSymbol> allPayloadsById, Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> packagesPayloads, IEnumerable<ISearchFacade> orderedSearches, string intermediateFolder)
22 { 22 {
23 this.Messaging = messaging; 23 this.Messaging = messaging;
24 this.BackendExtensions = backendExtensions; 24 this.BackendExtensions = backendExtensions;
@@ -31,6 +31,7 @@ namespace WixToolset.Core.Burn.Bundles
31 this.RollbackBoundaries = boundaries; 31 this.RollbackBoundaries = boundaries;
32 this.UXContainerPayloads = uxPayloads; 32 this.UXContainerPayloads = uxPayloads;
33 this.Payloads = allPayloadsById; 33 this.Payloads = allPayloadsById;
34 this.PackagesPayloads = packagesPayloads;
34 this.OrderedSearches = orderedSearches; 35 this.OrderedSearches = orderedSearches;
35 this.IntermediateFolder = intermediateFolder; 36 this.IntermediateFolder = intermediateFolder;
36 } 37 }
@@ -57,6 +58,8 @@ namespace WixToolset.Core.Burn.Bundles
57 58
58 private Dictionary<string, WixBundlePayloadSymbol> Payloads { get; } 59 private Dictionary<string, WixBundlePayloadSymbol> Payloads { get; }
59 60
61 private Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> PackagesPayloads { get; }
62
60 private IEnumerable<WixBundleContainerSymbol> Containers { get; } 63 private IEnumerable<WixBundleContainerSymbol> Containers { get; }
61 64
62 private IEnumerable<WixBundlePayloadSymbol> UXContainerPayloads { get; } 65 private IEnumerable<WixBundlePayloadSymbol> UXContainerPayloads { get; }
@@ -328,7 +331,6 @@ namespace WixToolset.Core.Burn.Bundles
328 var targetCodesByPatch = this.Section.Symbols.OfType<WixBundlePatchTargetCodeSymbol>().ToLookup(r => r.PackageRef); 331 var targetCodesByPatch = this.Section.Symbols.OfType<WixBundlePatchTargetCodeSymbol>().ToLookup(r => r.PackageRef);
329 var msiFeaturesByPackage = this.Section.Symbols.OfType<WixBundleMsiFeatureSymbol>().ToLookup(r => r.PackageRef); 332 var msiFeaturesByPackage = this.Section.Symbols.OfType<WixBundleMsiFeatureSymbol>().ToLookup(r => r.PackageRef);
330 var msiPropertiesByPackage = this.Section.Symbols.OfType<WixBundleMsiPropertySymbol>().ToLookup(r => r.PackageRef); 333 var msiPropertiesByPackage = this.Section.Symbols.OfType<WixBundleMsiPropertySymbol>().ToLookup(r => r.PackageRef);
331 var payloadsByPackage = this.Payloads.Values.ToLookup(p => p.PackageRef);
332 var relatedPackagesByPackage = this.Section.Symbols.OfType<WixBundleRelatedPackageSymbol>().ToLookup(r => r.PackageRef); 334 var relatedPackagesByPackage = this.Section.Symbols.OfType<WixBundleRelatedPackageSymbol>().ToLookup(r => r.PackageRef);
333 var slipstreamMspsByPackage = this.Section.Symbols.OfType<WixBundleSlipstreamMspSymbol>().ToLookup(r => r.TargetPackageRef); 335 var slipstreamMspsByPackage = this.Section.Symbols.OfType<WixBundleSlipstreamMspSymbol>().ToLookup(r => r.TargetPackageRef);
334 var exitCodesByPackage = this.Section.Symbols.OfType<WixBundlePackageExitCodeSymbol>().ToLookup(r => r.ChainPackageId); 336 var exitCodesByPackage = this.Section.Symbols.OfType<WixBundlePackageExitCodeSymbol>().ToLookup(r => r.ChainPackageId);
@@ -569,9 +571,9 @@ namespace WixToolset.Core.Burn.Bundles
569 writer.WriteAttributeString("Id", packagePayloadId); 571 writer.WriteAttributeString("Id", packagePayloadId);
570 writer.WriteEndElement(); 572 writer.WriteEndElement();
571 573
572 var packagePayloads = payloadsByPackage[package.PackageId]; 574 var packagePayloads = this.PackagesPayloads[package.PackageId];
573 575
574 foreach (var payload in packagePayloads) 576 foreach (var payload in packagePayloads.Values)
575 { 577 {
576 if (payload.Id.Id != packagePayloadId) 578 if (payload.Id.Id != packagePayloadId)
577 { 579 {
diff --git a/src/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs b/src/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs
index dacff364..b8b256fd 100644
--- a/src/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs
@@ -27,6 +27,7 @@ namespace WixToolset.Core.Burn.Bundles
27 27
28 public void Execute() 28 public void Execute()
29 { 29 {
30 var wixGroupPackagesGroupedById = this.Section.Symbols.OfType<WixGroupSymbol>().Where(g => g.ParentType == ComplexReferenceParentType.Package).ToLookup(g => g.ParentId);
30 var exePackages = this.Section.Symbols.OfType<WixBundleExePackageSymbol>().ToDictionary(t => t.Id.Id); 31 var exePackages = this.Section.Symbols.OfType<WixBundleExePackageSymbol>().ToDictionary(t => t.Id.Id);
31 var msiPackages = this.Section.Symbols.OfType<WixBundleMsiPackageSymbol>().ToDictionary(t => t.Id.Id); 32 var msiPackages = this.Section.Symbols.OfType<WixBundleMsiPackageSymbol>().ToDictionary(t => t.Id.Id);
32 var mspPackages = this.Section.Symbols.OfType<WixBundleMspPackageSymbol>().ToDictionary(t => t.Id.Id); 33 var mspPackages = this.Section.Symbols.OfType<WixBundleMspPackageSymbol>().ToDictionary(t => t.Id.Id);
@@ -43,7 +44,7 @@ namespace WixToolset.Core.Burn.Bundles
43 var id = package.Id.Id; 44 var id = package.Id.Id;
44 45
45 IntermediateSymbol packagePayload = null; 46 IntermediateSymbol packagePayload = null;
46 foreach (var wixGroup in this.Section.Symbols.OfType<WixGroupSymbol>().Where(g => g.ParentType == ComplexReferenceParentType.Package && g.ParentId == id)) 47 foreach (var wixGroup in wixGroupPackagesGroupedById[id])
47 { 48 {
48 if (wixGroup.ChildType == ComplexReferenceChildType.PackagePayload) 49 if (wixGroup.ChildType == ComplexReferenceChildType.PackagePayload)
49 { 50 {
diff --git a/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs b/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
index c8867eb7..4bc40011 100644
--- a/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
@@ -23,7 +23,7 @@ namespace WixToolset.Core.Burn.Bundles
23 { 23 {
24 private const string PropertySqlFormat = "SELECT `Value` FROM `Property` WHERE `Property` = '{0}'"; 24 private const string PropertySqlFormat = "SELECT `Value` FROM `Property` WHERE `Property` = '{0}'";
25 25
26 public ProcessMsiPackageCommand(IServiceProvider serviceProvider, IEnumerable<IBurnBackendBinderExtension> backendExtensions, IntermediateSection section, PackageFacade facade, Dictionary<string, WixBundlePayloadSymbol> payloadSymbols) 26 public ProcessMsiPackageCommand(IServiceProvider serviceProvider, IEnumerable<IBurnBackendBinderExtension> backendExtensions, IntermediateSection section, PackageFacade facade, Dictionary<string, WixBundlePayloadSymbol> packagePayloads)
27 { 27 {
28 this.Messaging = serviceProvider.GetService<IMessaging>(); 28 this.Messaging = serviceProvider.GetService<IMessaging>();
29 this.BackendHelper = serviceProvider.GetService<IBackendHelper>(); 29 this.BackendHelper = serviceProvider.GetService<IBackendHelper>();
@@ -31,7 +31,7 @@ namespace WixToolset.Core.Burn.Bundles
31 31
32 this.BackendExtensions = backendExtensions; 32 this.BackendExtensions = backendExtensions;
33 33
34 this.AuthoredPayloads = payloadSymbols; 34 this.PackagePayloads = packagePayloads;
35 this.Section = section; 35 this.Section = section;
36 this.Facade = facade; 36 this.Facade = facade;
37 } 37 }
@@ -44,7 +44,7 @@ namespace WixToolset.Core.Burn.Bundles
44 44
45 private IEnumerable<IBurnBackendBinderExtension> BackendExtensions { get; } 45 private IEnumerable<IBurnBackendBinderExtension> BackendExtensions { get; }
46 46
47 private Dictionary<string, WixBundlePayloadSymbol> AuthoredPayloads { get; } 47 private Dictionary<string, WixBundlePayloadSymbol> PackagePayloads { get; }
48 48
49 private PackageFacade Facade { get; } 49 private PackageFacade Facade { get; }
50 50
@@ -55,7 +55,7 @@ namespace WixToolset.Core.Burn.Bundles
55 /// </summary> 55 /// </summary>
56 public void Execute() 56 public void Execute()
57 { 57 {
58 var packagePayload = this.AuthoredPayloads[this.Facade.PackageSymbol.PayloadRef]; 58 var packagePayload = this.PackagePayloads[this.Facade.PackageSymbol.PayloadRef];
59 59
60 var msiPackage = (WixBundleMsiPackageSymbol)this.Facade.SpecificPackageSymbol; 60 var msiPackage = (WixBundleMsiPackageSymbol)this.Facade.SpecificPackageSymbol;
61 61
@@ -182,9 +182,7 @@ namespace WixToolset.Core.Burn.Bundles
182 182
183 private ISet<string> GetPayloadTargetNames(string packageId) 183 private ISet<string> GetPayloadTargetNames(string packageId)
184 { 184 {
185 var payloadNames = this.Section.Symbols.OfType<WixBundlePayloadSymbol>() 185 var payloadNames = this.PackagePayloads.Values.Select(p => p.Name);
186 .Where(p => p.PackageRef == packageId)
187 .Select(p => p.Name);
188 186
189 return new HashSet<string>(payloadNames, StringComparer.OrdinalIgnoreCase); 187 return new HashSet<string>(payloadNames, StringComparer.OrdinalIgnoreCase);
190 } 188 }
@@ -397,13 +395,20 @@ namespace WixToolset.Core.Burn.Bundles
397 var generatedId = this.BackendHelper.GenerateIdentifier("cab", packagePayload.Id.Id, cabinet); 395 var generatedId = this.BackendHelper.GenerateIdentifier("cab", packagePayload.Id.Id, cabinet);
398 var payloadSourceFile = this.ResolveRelatedFile(packagePayload.SourceFile.Path, packagePayload.UnresolvedSourceFile, cabinet, "Cabinet", this.Facade.PackageSymbol.SourceLineNumbers); 396 var payloadSourceFile = this.ResolveRelatedFile(packagePayload.SourceFile.Path, packagePayload.UnresolvedSourceFile, cabinet, "Cabinet", this.Facade.PackageSymbol.SourceLineNumbers);
399 397
398 this.Section.AddSymbol(new WixGroupSymbol(this.Facade.PackageSymbol.SourceLineNumbers)
399 {
400 ParentType = ComplexReferenceParentType.Package,
401 ParentId = this.Facade.PackageId,
402 ChildType = ComplexReferenceChildType.Payload,
403 ChildId = generatedId
404 });
405
400 this.Section.AddSymbol(new WixBundlePayloadSymbol(this.Facade.PackageSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId)) 406 this.Section.AddSymbol(new WixBundlePayloadSymbol(this.Facade.PackageSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId))
401 { 407 {
402 Name = cabinetName, 408 Name = cabinetName,
403 SourceFile = new IntermediateFieldPathValue { Path = payloadSourceFile }, 409 SourceFile = new IntermediateFieldPathValue { Path = payloadSourceFile },
404 Compressed = packagePayload.Compressed, 410 Compressed = packagePayload.Compressed,
405 UnresolvedSourceFile = cabinetName, 411 UnresolvedSourceFile = cabinetName,
406 PackageRef = packagePayload.PackageRef,
407 ContainerRef = packagePayload.ContainerRef, 412 ContainerRef = packagePayload.ContainerRef,
408 ContentFile = true, 413 ContentFile = true,
409 Packaging = packagePayload.Packaging, 414 Packaging = packagePayload.Packaging,
@@ -466,7 +471,7 @@ namespace WixToolset.Core.Burn.Bundles
466 if (WindowsInstallerConstants.MsidbFileAttributesNoncompressed == (compressionBit & WindowsInstallerConstants.MsidbFileAttributesNoncompressed) || 471 if (WindowsInstallerConstants.MsidbFileAttributesNoncompressed == (compressionBit & WindowsInstallerConstants.MsidbFileAttributesNoncompressed) ||
467 (!compressed && 0 == (compressionBit & WindowsInstallerConstants.MsidbFileAttributesCompressed))) 472 (!compressed && 0 == (compressionBit & WindowsInstallerConstants.MsidbFileAttributesCompressed)))
468 { 473 {
469 string fileSourcePath = this.PathResolver.GetFileSourcePath(directories, record.GetString(1), record.GetString(3), compressed, longNamesInImage); 474 var fileSourcePath = this.PathResolver.GetFileSourcePath(directories, record.GetString(1), record.GetString(3), compressed, longNamesInImage);
470 var name = Path.Combine(Path.GetDirectoryName(packagePayload.Name), fileSourcePath); 475 var name = Path.Combine(Path.GetDirectoryName(packagePayload.Name), fileSourcePath);
471 476
472 if (!payloadNames.Contains(name)) 477 if (!payloadNames.Contains(name))
@@ -474,13 +479,20 @@ namespace WixToolset.Core.Burn.Bundles
474 var generatedId = this.BackendHelper.GenerateIdentifier("f", packagePayload.Id.Id, record.GetString(2)); 479 var generatedId = this.BackendHelper.GenerateIdentifier("f", packagePayload.Id.Id, record.GetString(2));
475 var payloadSourceFile = this.ResolveRelatedFile(packagePayload.SourceFile.Path, packagePayload.UnresolvedSourceFile, fileSourcePath, "File", this.Facade.PackageSymbol.SourceLineNumbers); 480 var payloadSourceFile = this.ResolveRelatedFile(packagePayload.SourceFile.Path, packagePayload.UnresolvedSourceFile, fileSourcePath, "File", this.Facade.PackageSymbol.SourceLineNumbers);
476 481
482 this.Section.AddSymbol(new WixGroupSymbol(this.Facade.PackageSymbol.SourceLineNumbers)
483 {
484 ParentType = ComplexReferenceParentType.Package,
485 ParentId = this.Facade.PackageId,
486 ChildType = ComplexReferenceChildType.Payload,
487 ChildId = generatedId
488 });
489
477 this.Section.AddSymbol(new WixBundlePayloadSymbol(this.Facade.PackageSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId)) 490 this.Section.AddSymbol(new WixBundlePayloadSymbol(this.Facade.PackageSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId))
478 { 491 {
479 Name = name, 492 Name = name,
480 SourceFile = new IntermediateFieldPathValue { Path = payloadSourceFile }, 493 SourceFile = new IntermediateFieldPathValue { Path = payloadSourceFile },
481 Compressed = packagePayload.Compressed, 494 Compressed = packagePayload.Compressed,
482 UnresolvedSourceFile = name, 495 UnresolvedSourceFile = name,
483 PackageRef = packagePayload.PackageRef,
484 ContainerRef = packagePayload.ContainerRef, 496 ContainerRef = packagePayload.ContainerRef,
485 ContentFile = true, 497 ContentFile = true,
486 Packaging = packagePayload.Packaging, 498 Packaging = packagePayload.Packaging,
diff --git a/src/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs b/src/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs
index 20044235..7ec3104c 100644
--- a/src/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs
+++ b/src/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs
@@ -94,7 +94,7 @@ namespace WixToolsetTest.CoreIntegration
94 } 94 }
95 } 95 }
96 96
97 [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6370")] 97 [Fact]
98 public void PopulatesBAManifestWithPayloadInformation() 98 public void PopulatesBAManifestWithPayloadInformation()
99 { 99 {
100 var folder = TestData.Get(@"TestData"); 100 var folder = TestData.Get(@"TestData");
@@ -131,10 +131,10 @@ namespace WixToolsetTest.CoreIntegration
131 { "WixPayloadProperties", new List<string> { "Size" } }, 131 { "WixPayloadProperties", new List<string> { "Size" } },
132 }; 132 };
133 Assert.Equal(4, payloadElements.Count); 133 Assert.Equal(4, payloadElements.Count);
134 Assert.Equal("<WixPayloadProperties Payload='credwiz.exe' Package='credwiz.exe' Container='WixAttachedContainer' Name='credwiz.exe' Size='*' LayoutOnly='no' />", payloadElements[0].GetTestXml(ignoreAttributesByElementName)); 134 Assert.Equal("<WixPayloadProperties Package='credwiz.exe' Payload='SourceFilePayload' Container='WixAttachedContainer' Name='SharedPayloadsBetweenPackages.wxs' Size='*' LayoutOnly='no' />", payloadElements[0].GetTestXml(ignoreAttributesByElementName));
135 Assert.Equal("<WixPayloadProperties Payload='payue_e5DuhsDGlzJxWYPhqr6S7rkc' Package='credwiz.exe' Container='WixAttachedContainer' Name='SharedPayloadsBetweenPackages.wxs' Size='*' LayoutOnly='no' />", payloadElements[1].GetTestXml(ignoreAttributesByElementName)); 135 Assert.Equal("<WixPayloadProperties Package='credwiz.exe' Payload='credwiz.exe' Container='WixAttachedContainer' Name='credwiz.exe' Size='*' LayoutOnly='no' />", payloadElements[1].GetTestXml(ignoreAttributesByElementName));
136 Assert.Equal("<WixPayloadProperties Payload='cscript.exe' Package='cscript.exe' Container='WixAttachedContainer' Name='cscript.exe' Size='*' LayoutOnly='no' />", payloadElements[2].GetTestXml(ignoreAttributesByElementName)); 136 Assert.Equal("<WixPayloadProperties Package='cscript.exe' Payload='SourceFilePayload' Container='WixAttachedContainer' Name='SharedPayloadsBetweenPackages.wxs' Size='*' LayoutOnly='no' />", payloadElements[2].GetTestXml(ignoreAttributesByElementName));
137 Assert.Equal("<WixPayloadProperties Payload='payue_e5DuhsDGlzJxWYPhqr6S7rkc' Package='cscript.exe' Container='WixAttachedContainer' Name='SharedPayloadsBetweenPackages.wxs' Size='*' LayoutOnly='no' />", payloadElements[3].GetTestXml(ignoreAttributesByElementName)); 137 Assert.Equal("<WixPayloadProperties Package='cscript.exe' Payload='cscript.exe' Container='WixAttachedContainer' Name='cscript.exe' Size='*' LayoutOnly='no' />", payloadElements[3].GetTestXml(ignoreAttributesByElementName));
138 } 138 }
139 } 139 }
140 140
diff --git a/src/test/WixToolsetTest.CoreIntegration/TestData/SharedPayloadsBetweenPackages/SharedPayloadsBetweenPackages.wxs b/src/test/WixToolsetTest.CoreIntegration/TestData/SharedPayloadsBetweenPackages/SharedPayloadsBetweenPackages.wxs
index 2588ffc1..3457a3b7 100644
--- a/src/test/WixToolsetTest.CoreIntegration/TestData/SharedPayloadsBetweenPackages/SharedPayloadsBetweenPackages.wxs
+++ b/src/test/WixToolsetTest.CoreIntegration/TestData/SharedPayloadsBetweenPackages/SharedPayloadsBetweenPackages.wxs
@@ -12,7 +12,7 @@
12 </Fragment> 12 </Fragment>
13 <Fragment> 13 <Fragment>
14 <PayloadGroup Id="SharedPayloads"> 14 <PayloadGroup Id="SharedPayloads">
15 <Payload SourceFile="$(sys.SOURCEFILEPATH)" /> 15 <Payload Id="SourceFilePayload" SourceFile="$(sys.SOURCEFILEPATH)" />
16 </PayloadGroup> 16 </PayloadGroup>
17 </Fragment> 17 </Fragment>
18</Wix> 18</Wix>