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[]