@joebigelow / wix / commits / 8b7545c2

Include LayoutOnly payloads in BootstrapperApplicationData.xml.

#6399

Sean Hall committed Apr 24, 2021 at 17:46 UTC 8b7545c2b692098957cc5737e92415bbe4f7823d
4 files changed +91 -23
src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+1 -1
@@ -390,7 +390,7 @@ namespace WixToolset.Core.Burn
390 // Generate the core-defined BA manifest tables...
391 string baManifestPath;
392 {
393 - var command = new CreateBootstrapperApplicationManifestCommand(section, bundleSymbol, orderedFacades, uxPayloadIndex, packagesPayloads, this.IntermediateFolder, this.InternalBurnBackendHelper);
393 + var command = new CreateBootstrapperApplicationManifestCommand(section, bundleSymbol, orderedFacades, uxPayloadIndex, payloadSymbols, packagesPayloads, this.IntermediateFolder, this.InternalBurnBackendHelper);
394 command.Execute();
395
396 var baManifestPayload = command.BootstrapperApplicationManifestPayloadRow;
src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
+31 -18
@@ -15,12 +15,13 @@ namespace WixToolset.Core.Burn.Bundles
15
16 internal class CreateBootstrapperApplicationManifestCommand
17 {
18 - public CreateBootstrapperApplicationManifestCommand(IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<PackageFacade> chainPackages, int lastUXPayloadIndex, Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> packagesPayloads, string intermediateFolder, IInternalBurnBackendHelper internalBurnBackendHelper)
18 + public CreateBootstrapperApplicationManifestCommand(IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<PackageFacade> chainPackages, int lastUXPayloadIndex, Dictionary<string, WixBundlePayloadSymbol> payloadSymbols, Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> packagesPayloads, string intermediateFolder, IInternalBurnBackendHelper internalBurnBackendHelper)
19 {
20 this.Section = section;
21 this.BundleSymbol = bundleSymbol;
22 this.ChainPackages = chainPackages;
23 this.LastUXPayloadIndex = lastUXPayloadIndex;
24 + this.Payloads = payloadSymbols;
25 this.PackagesPayloads = packagesPayloads;
26 this.IntermediateFolder = intermediateFolder;
27 this.InternalBurnBackendHelper = internalBurnBackendHelper;
@@ -36,6 +37,8 @@ namespace WixToolset.Core.Burn.Bundles
37
38 private int LastUXPayloadIndex { get; }
39
40 + private Dictionary<string, WixBundlePayloadSymbol> Payloads { get; }
41 +
42 private Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> PackagesPayloads { get; }
43
44 private string IntermediateFolder { get; }
@@ -216,7 +219,6 @@ namespace WixToolset.Core.Burn.Bundles
219
220 private void WritePayloadInfo(XmlTextWriter writer)
221 {
219 - // TODO: check v3 - should this be only include package payloads or include all non-UX container payloads?
222 foreach (var kvp in this.PackagesPayloads.OrderBy(kvp => kvp.Key, StringComparer.Ordinal))
223 {
224 var packageId = kvp.Key;
@@ -224,30 +226,41 @@ namespace WixToolset.Core.Burn.Bundles
226
227 foreach (var payloadSymbol in payloadsById.Values.OrderBy(p => p.Id.Id, StringComparer.Ordinal))
228 {
227 - writer.WriteStartElement("WixPayloadProperties");
229 + this.WritePayloadInfo(writer, payloadSymbol, packageId);
230 + }
231 + }
232
229 - writer.WriteAttributeString("Package", packageId);
233 + foreach (var payloadSymbol in this.Payloads.Values.Where(p => p.LayoutOnly).OrderBy(p => p.Id.Id, StringComparer.Ordinal))
234 + {
235 + this.WritePayloadInfo(writer, payloadSymbol, null);
236 + }
237 + }
238
231 - writer.WriteAttributeString("Payload", payloadSymbol.Id.Id);
239 + private void WritePayloadInfo(XmlTextWriter writer, WixBundlePayloadSymbol payloadSymbol, string packageId)
240 + {
241 + writer.WriteStartElement("WixPayloadProperties");
242
233 - if (!String.IsNullOrEmpty(payloadSymbol.ContainerRef))
234 - {
235 - writer.WriteAttributeString("Container", payloadSymbol.ContainerRef);
236 - }
243 + if (!String.IsNullOrEmpty(packageId))
244 + {
245 + writer.WriteAttributeString("Package", packageId);
246 + }
247
238 - writer.WriteAttributeString("Name", payloadSymbol.Name);
239 - writer.WriteAttributeString("Size", payloadSymbol.FileSize.Value.ToString(CultureInfo.InvariantCulture));
248 + writer.WriteAttributeString("Payload", payloadSymbol.Id.Id);
249
241 - if (!String.IsNullOrEmpty(payloadSymbol.DownloadUrl))
242 - {
243 - writer.WriteAttributeString("DownloadUrl", payloadSymbol.DownloadUrl);
244 - }
250 + if (!String.IsNullOrEmpty(payloadSymbol.ContainerRef))
251 + {
252 + writer.WriteAttributeString("Container", payloadSymbol.ContainerRef);
253 + }
254
246 - writer.WriteAttributeString("LayoutOnly", payloadSymbol.LayoutOnly ? "yes" : "no");
255 + writer.WriteAttributeString("Name", payloadSymbol.Name);
256 + writer.WriteAttributeString("Size", payloadSymbol.FileSize.Value.ToString(CultureInfo.InvariantCulture));
257
248 - writer.WriteEndElement();
249 - }
258 + if (!String.IsNullOrEmpty(payloadSymbol.DownloadUrl))
259 + {
260 + writer.WriteAttributeString("DownloadUrl", payloadSymbol.DownloadUrl);
261 }
262 +
263 + writer.WriteEndElement();
264 }
265
266 private WixBundlePayloadSymbol CreateBootstrapperApplicationManifestPayloadRow(string baManifestPath)
src/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs
+4 -4
@@ -131,10 +131,10 @@ namespace WixToolsetTest.CoreIntegration
131 { "WixPayloadProperties", new List<string> { "Size" } },
132 };
133 Assert.Equal(4, payloadElements.Count);
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 Package='credwiz.exe' Payload='credwiz.exe' Container='WixAttachedContainer' Name='credwiz.exe' Size='*' LayoutOnly='no' />", payloadElements[1].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 Package='cscript.exe' Payload='cscript.exe' Container='WixAttachedContainer' Name='cscript.exe' Size='*' LayoutOnly='no' />", payloadElements[3].GetTestXml(ignoreAttributesByElementName));
134 + Assert.Equal("<WixPayloadProperties Package='credwiz.exe' Payload='SourceFilePayload' Container='WixAttachedContainer' Name='SharedPayloadsBetweenPackages.wxs' Size='*' />", payloadElements[0].GetTestXml(ignoreAttributesByElementName));
135 + Assert.Equal("<WixPayloadProperties Package='credwiz.exe' Payload='credwiz.exe' Container='WixAttachedContainer' Name='credwiz.exe' Size='*' />", payloadElements[1].GetTestXml(ignoreAttributesByElementName));
136 + Assert.Equal("<WixPayloadProperties Package='cscript.exe' Payload='SourceFilePayload' Container='WixAttachedContainer' Name='SharedPayloadsBetweenPackages.wxs' Size='*' />", payloadElements[2].GetTestXml(ignoreAttributesByElementName));
137 + Assert.Equal("<WixPayloadProperties Package='cscript.exe' Payload='cscript.exe' Container='WixAttachedContainer' Name='cscript.exe' Size='*' />", payloadElements[3].GetTestXml(ignoreAttributesByElementName));
138 }
139 }
140
src/test/WixToolsetTest.CoreIntegration/ContainerFixture.cs
+55
@@ -254,6 +254,61 @@ namespace WixToolsetTest.CoreIntegration
254 }
255 }
256
257 + [Fact]
258 + public void PopulatesBAManifestWithLayoutOnlyPayloads()
259 + {
260 + var folder = TestData.Get(@"TestData");
261 +
262 + using (var fs = new DisposableFileSystem())
263 + {
264 + var baseFolder = fs.GetFolder();
265 + var intermediateFolder = Path.Combine(baseFolder, "obj");
266 + var binFolder = Path.Combine(baseFolder, "bin");
267 + var bundlePath = Path.Combine(binFolder, "test.exe");
268 + var baFolderPath = Path.Combine(baseFolder, "ba");
269 + var extractFolderPath = Path.Combine(baseFolder, "extract");
270 +
271 + this.BuildMsis(folder, intermediateFolder, binFolder);
272 +
273 + var result = WixRunner.Execute(false, new[]
274 + {
275 + "build",
276 + Path.Combine(folder, "Container", "LayoutPayloadInContainer.wxs"),
277 + "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
278 + "-bindpath", binFolder,
279 + "-intermediateFolder", intermediateFolder,
280 + "-o", bundlePath
281 + });
282 +
283 + WixAssert.CompareLineByLine(new string[]
284 + {
285 + "The layout-only Payload 'SharedPayload' is being added to Container 'FirstX64'. It will not be extracted during layout.",
286 + }, result.Messages.Select(m => m.ToString()).ToArray());
287 + result.AssertSuccess();
288 +
289 + Assert.True(File.Exists(bundlePath));
290 +
291 + var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath);
292 + extractResult.AssertSuccess();
293 +
294 + var ignoreAttributesByElementName = new Dictionary<string, List<string>>
295 + {
296 + { "WixPayloadProperties", new List<string> { "Size" } },
297 + };
298 + var payloads = extractResult.SelectBADataNodes("/ba:BootstrapperApplicationData/ba:WixPayloadProperties")
299 + .Cast<XmlElement>()
300 + .Select(e => e.GetTestXml(ignoreAttributesByElementName))
301 + .ToArray();
302 + WixAssert.CompareLineByLine(new string[]
303 + {
304 + "<WixPayloadProperties Package='FirstX64.msi' Payload='FirstX64.msi' Container='FirstX64' Name='FirstX64.msi' Size='*' />",
305 + "<WixPayloadProperties Package='FirstX64.msi' Payload='SharedPayload' Container='FirstX64' Name='LayoutPayloadInContainer.wxs' Size='*' />",
306 + "<WixPayloadProperties Package='FirstX64.msi' Payload='fC0n41rZK8oW3JK8LzHu6AT3CjdQ' Container='FirstX64' Name='PFiles\\MsiPackage\\test.txt' Size='*' />",
307 + "<WixPayloadProperties Payload='SharedPayload' Container='FirstX64' Name='LayoutPayloadInContainer.wxs' Size='*' />",
308 + }, payloads);
309 + }
310 + }
311 +
312 private void BuildMsis(string folder, string intermediateFolder, string binFolder)
313 {
314 var result = WixRunner.Execute(new[]