Change harvested symbols to ref the package payload for remote support.
Sean Hall committed
Apr 13, 2022 at 10:14 UTC
3704a5547766581b15690b6535d03568afcfc2a0
22 files changed
+461
-161
src/api/wix/WixToolset.Data/Symbols/SymbolDefinitions.cs
+4
@@ -131,6 +131,7 @@ namespace WixToolset.Data
131
WixBundleExePackagePayload,
132
WixBundleExtension,
133
WixBundleHarvestedBundlePackage,
134
+ WixBundleHarvestedDependencyProvider,
135
WixBundleHarvestedMsiPackage,
136
WixBundleHarvestedMspPackage,
137
WixBundleMsiFeature,
@@ -589,6 +590,9 @@ namespace WixToolset.Data
590
case SymbolDefinitionType.WixBundleHarvestedBundlePackage:
591
return SymbolDefinitions.WixBundleHarvestedBundlePackage;
592
593
+ case SymbolDefinitionType.WixBundleHarvestedDependencyProvider:
594
+ return SymbolDefinitions.WixBundleHarvestedDependencyProvider;
595
+
596
case SymbolDefinitionType.WixBundleHarvestedMsiPackage:
597
return SymbolDefinitions.WixBundleHarvestedMsiPackage;
598
src/api/wix/WixToolset.Data/Symbols/WixBundleHarvestedDependencyProviderSymbol.cs
new
+93
@@ -0,0 +1,93 @@
1
+// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
+
3
+namespace WixToolset.Data
4
+{
5
+ using WixToolset.Data.Symbols;
6
+
7
+ public static partial class SymbolDefinitions
8
+ {
9
+ public static readonly IntermediateSymbolDefinition WixBundleHarvestedDependencyProvider = new IntermediateSymbolDefinition(
10
+ SymbolDefinitionType.WixBundleHarvestedDependencyProvider,
11
+ new[]
12
+ {
13
+ new IntermediateFieldDefinition(nameof(WixBundleHarvestedDependencyProviderSymbolFields.PackagePayloadRef), IntermediateFieldType.String),
14
+ new IntermediateFieldDefinition(nameof(WixBundleHarvestedDependencyProviderSymbolFields.Attributes), IntermediateFieldType.Number),
15
+ new IntermediateFieldDefinition(nameof(WixBundleHarvestedDependencyProviderSymbolFields.ProviderKey), IntermediateFieldType.String),
16
+ new IntermediateFieldDefinition(nameof(WixBundleHarvestedDependencyProviderSymbolFields.Version), IntermediateFieldType.String),
17
+ new IntermediateFieldDefinition(nameof(WixBundleHarvestedDependencyProviderSymbolFields.DisplayName), IntermediateFieldType.String),
18
+ new IntermediateFieldDefinition(nameof(WixBundleHarvestedDependencyProviderSymbolFields.ProviderAttributes), IntermediateFieldType.Number),
19
+ },
20
+ typeof(WixDependencyProviderSymbol));
21
+ }
22
+}
23
+
24
+namespace WixToolset.Data.Symbols
25
+{
26
+ using System;
27
+ using WixToolset.Data;
28
+
29
+ public enum WixBundleHarvestedDependencyProviderSymbolFields
30
+ {
31
+ PackagePayloadRef,
32
+ Attributes,
33
+ ProviderKey,
34
+ Version,
35
+ DisplayName,
36
+ ProviderAttributes,
37
+ }
38
+
39
+ [Flags]
40
+ public enum WixBundleHarvestedDependencyProviderAttributes
41
+ {
42
+ None = 0x0,
43
+ }
44
+
45
+ public class WixBundleHarvestedDependencyProviderSymbol : IntermediateSymbol
46
+ {
47
+ public WixBundleHarvestedDependencyProviderSymbol() : base(SymbolDefinitions.WixBundleHarvestedDependencyProvider, null, null)
48
+ {
49
+ }
50
+
51
+ public WixBundleHarvestedDependencyProviderSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(SymbolDefinitions.WixBundleHarvestedDependencyProvider, sourceLineNumber, id)
52
+ {
53
+ }
54
+
55
+ public IntermediateField this[WixBundleHarvestedDependencyProviderSymbolFields index] => this.Fields[(int)index];
56
+
57
+ public string PackagePayloadRef
58
+ {
59
+ get => this.Fields[(int)WixBundleHarvestedDependencyProviderSymbolFields.PackagePayloadRef].AsString();
60
+ set => this.Set((int)WixBundleHarvestedDependencyProviderSymbolFields.PackagePayloadRef, value);
61
+ }
62
+
63
+ public WixBundleHarvestedDependencyProviderAttributes Attributes
64
+ {
65
+ get => (WixBundleHarvestedDependencyProviderAttributes)this.Fields[(int)WixBundleHarvestedDependencyProviderSymbolFields.Attributes].AsNumber();
66
+ set => this.Set((int)WixBundleHarvestedDependencyProviderSymbolFields.Attributes, (int)value);
67
+ }
68
+
69
+ public string ProviderKey
70
+ {
71
+ get => this.Fields[(int)WixBundleHarvestedDependencyProviderSymbolFields.ProviderKey].AsString();
72
+ set => this.Set((int)WixBundleHarvestedDependencyProviderSymbolFields.ProviderKey, value);
73
+ }
74
+
75
+ public string Version
76
+ {
77
+ get => this.Fields[(int)WixBundleHarvestedDependencyProviderSymbolFields.Version].AsString();
78
+ set => this.Set((int)WixBundleHarvestedDependencyProviderSymbolFields.Version, value);
79
+ }
80
+
81
+ public string DisplayName
82
+ {
83
+ get => this.Fields[(int)WixBundleHarvestedDependencyProviderSymbolFields.DisplayName].AsString();
84
+ set => this.Set((int)WixBundleHarvestedDependencyProviderSymbolFields.DisplayName, value);
85
+ }
86
+
87
+ public int ProviderAttributes
88
+ {
89
+ get => this.Fields[(int)WixBundleHarvestedDependencyProviderSymbolFields.ProviderAttributes].AsNumber();
90
+ set => this.Set((int)WixBundleHarvestedDependencyProviderSymbolFields.ProviderAttributes, value);
91
+ }
92
+ }
93
+}
src/api/wix/WixToolset.Data/Symbols/WixBundleMsiFeatureSymbol.cs
+5
-5
@@ -10,7 +10,7 @@ namespace WixToolset.Data
10
SymbolDefinitionType.WixBundleMsiFeature,
11
new[]
12
{
13
- new IntermediateFieldDefinition(nameof(WixBundleMsiFeatureSymbolFields.PackageRef), IntermediateFieldType.String),
13
+ new IntermediateFieldDefinition(nameof(WixBundleMsiFeatureSymbolFields.PackagePayloadRef), IntermediateFieldType.String),
14
new IntermediateFieldDefinition(nameof(WixBundleMsiFeatureSymbolFields.Name), IntermediateFieldType.String),
15
new IntermediateFieldDefinition(nameof(WixBundleMsiFeatureSymbolFields.Size), IntermediateFieldType.LargeNumber),
16
new IntermediateFieldDefinition(nameof(WixBundleMsiFeatureSymbolFields.Parent), IntermediateFieldType.String),
@@ -29,7 +29,7 @@ namespace WixToolset.Data.Symbols
29
{
30
public enum WixBundleMsiFeatureSymbolFields
31
{
32
- PackageRef,
32
+ PackagePayloadRef,
33
Name,
34
Size,
35
Parent,
@@ -53,10 +53,10 @@ namespace WixToolset.Data.Symbols
53
54
public IntermediateField this[WixBundleMsiFeatureSymbolFields index] => this.Fields[(int)index];
55
56
- public string PackageRef
56
+ public string PackagePayloadRef
57
{
58
- get => (string)this.Fields[(int)WixBundleMsiFeatureSymbolFields.PackageRef];
59
- set => this.Set((int)WixBundleMsiFeatureSymbolFields.PackageRef, value);
58
+ get => (string)this.Fields[(int)WixBundleMsiFeatureSymbolFields.PackagePayloadRef];
59
+ set => this.Set((int)WixBundleMsiFeatureSymbolFields.PackagePayloadRef, value);
60
}
61
62
public string Name
src/api/wix/WixToolset.Data/Symbols/WixBundlePackageRelatedBundleSymbol.cs
+5
-5
@@ -10,7 +10,7 @@ namespace WixToolset.Data
10
SymbolDefinitionType.WixBundlePackageRelatedBundle,
11
new[]
12
{
13
- new IntermediateFieldDefinition(nameof(WixBundlePackageRelatedBundleSymbolFields.PackageRef), IntermediateFieldType.String),
13
+ new IntermediateFieldDefinition(nameof(WixBundlePackageRelatedBundleSymbolFields.PackagePayloadRef), IntermediateFieldType.String),
14
new IntermediateFieldDefinition(nameof(WixBundlePackageRelatedBundleSymbolFields.BundleId), IntermediateFieldType.String),
15
new IntermediateFieldDefinition(nameof(WixBundlePackageRelatedBundleSymbolFields.Action), IntermediateFieldType.Number),
16
},
@@ -22,7 +22,7 @@ namespace WixToolset.Data.Symbols
22
{
23
public enum WixBundlePackageRelatedBundleSymbolFields
24
{
25
- PackageRef,
25
+ PackagePayloadRef,
26
BundleId,
27
Action,
28
}
@@ -39,10 +39,10 @@ namespace WixToolset.Data.Symbols
39
40
public IntermediateField this[WixBundlePackageRelatedBundleSymbolFields index] => this.Fields[(int)index];
41
42
- public string PackageRef
42
+ public string PackagePayloadRef
43
{
44
- get => (string)this.Fields[(int)WixBundlePackageRelatedBundleSymbolFields.PackageRef];
45
- set => this.Set((int)WixBundlePackageRelatedBundleSymbolFields.PackageRef, value);
44
+ get => (string)this.Fields[(int)WixBundlePackageRelatedBundleSymbolFields.PackagePayloadRef];
45
+ set => this.Set((int)WixBundlePackageRelatedBundleSymbolFields.PackagePayloadRef, value);
46
}
47
48
public string BundleId
src/api/wix/WixToolset.Data/Symbols/WixBundlePatchTargetCodeSymbol.cs
+5
-5
@@ -10,7 +10,7 @@ namespace WixToolset.Data
10
SymbolDefinitionType.WixBundlePatchTargetCode,
11
new[]
12
{
13
- new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.PackageRef), IntermediateFieldType.String),
13
+ new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.PackagePayloadRef), IntermediateFieldType.String),
14
new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.TargetCode), IntermediateFieldType.String),
15
new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.Attributes), IntermediateFieldType.Number),
16
new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.Type), IntermediateFieldType.Number),
@@ -25,7 +25,7 @@ namespace WixToolset.Data.Symbols
25
26
public enum WixBundlePatchTargetCodeSymbolFields
27
{
28
- PackageRef,
28
+ PackagePayloadRef,
29
TargetCode,
30
Attributes,
31
Type,
@@ -67,10 +67,10 @@ namespace WixToolset.Data.Symbols
67
68
public IntermediateField this[WixBundlePatchTargetCodeSymbolFields index] => this.Fields[(int)index];
69
70
- public string PackageRef
70
+ public string PackagePayloadRef
71
{
72
- get => (string)this.Fields[(int)WixBundlePatchTargetCodeSymbolFields.PackageRef];
73
- set => this.Set((int)WixBundlePatchTargetCodeSymbolFields.PackageRef, value);
72
+ get => (string)this.Fields[(int)WixBundlePatchTargetCodeSymbolFields.PackagePayloadRef];
73
+ set => this.Set((int)WixBundlePatchTargetCodeSymbolFields.PackagePayloadRef, value);
74
}
75
76
public string TargetCode
src/api/wix/WixToolset.Data/Symbols/WixBundleRelatedPackageSymbol.cs
+5
-5
@@ -10,7 +10,7 @@ namespace WixToolset.Data
10
SymbolDefinitionType.WixBundleRelatedPackage,
11
new[]
12
{
13
- new IntermediateFieldDefinition(nameof(WixBundleRelatedPackageSymbolFields.PackageRef), IntermediateFieldType.String),
13
+ new IntermediateFieldDefinition(nameof(WixBundleRelatedPackageSymbolFields.PackagePayloadRef), IntermediateFieldType.String),
14
new IntermediateFieldDefinition(nameof(WixBundleRelatedPackageSymbolFields.RelatedId), IntermediateFieldType.String),
15
new IntermediateFieldDefinition(nameof(WixBundleRelatedPackageSymbolFields.MinVersion), IntermediateFieldType.String),
16
new IntermediateFieldDefinition(nameof(WixBundleRelatedPackageSymbolFields.MaxVersion), IntermediateFieldType.String),
@@ -27,7 +27,7 @@ namespace WixToolset.Data.Symbols
27
28
public enum WixBundleRelatedPackageSymbolFields
29
{
30
- PackageRef,
30
+ PackagePayloadRef,
31
RelatedId,
32
MinVersion,
33
MaxVersion,
@@ -57,10 +57,10 @@ namespace WixToolset.Data.Symbols
57
58
public IntermediateField this[WixBundleRelatedPackageSymbolFields index] => this.Fields[(int)index];
59
60
- public string PackageRef
60
+ public string PackagePayloadRef
61
{
62
- get => (string)this.Fields[(int)WixBundleRelatedPackageSymbolFields.PackageRef];
63
- set => this.Set((int)WixBundleRelatedPackageSymbolFields.PackageRef, value);
62
+ get => (string)this.Fields[(int)WixBundleRelatedPackageSymbolFields.PackagePayloadRef];
63
+ set => this.Set((int)WixBundleRelatedPackageSymbolFields.PackagePayloadRef, value);
64
}
65
66
public string RelatedId
src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+9
-11
@@ -159,7 +159,7 @@ namespace WixToolset.Core.Burn
159
processedPayloads = new HashSet<string>(payloadSymbols.Keys);
160
}
161
162
- IDictionary<string, PackageFacade> facades;
162
+ PackageFacades facades;
163
{
164
var command = new GetPackageFacadesCommand(this.Messaging, chainPackageSymbols, section);
165
command.Execute();
@@ -325,7 +325,7 @@ namespace WixToolset.Core.Burn
325
326
// Determine patches to automatically slipstream.
327
{
328
- var command = new AutomaticallySlipstreamPatchesCommand(section, facades.Values);
328
+ var command = new AutomaticallySlipstreamPatchesCommand(this.Messaging, section, facades);
329
command.Execute();
330
}
331
@@ -334,13 +334,11 @@ namespace WixToolset.Core.Burn
334
return;
335
}
336
337
- IEnumerable<PackageFacade> orderedFacades;
337
IEnumerable<WixBundleRollbackBoundarySymbol> boundaries;
338
{
339
var command = new OrderPackagesAndRollbackBoundariesCommand(this.Messaging, section, facades);
340
command.Execute();
341
343
- orderedFacades = command.OrderedPackageFacades;
342
boundaries = command.UsedRollbackBoundaries;
343
}
344
@@ -351,7 +349,7 @@ namespace WixToolset.Core.Burn
349
}
350
351
{
354
- var command = new ProcessDependencyProvidersCommand(this.Messaging, section, facades);
352
+ var command = new ProcessDependencyProvidersCommand(this.ServiceProvider, section, facades);
353
command.Execute();
354
355
if (!String.IsNullOrEmpty(command.BundleProviderKey))
@@ -361,7 +359,7 @@ namespace WixToolset.Core.Burn
359
}
360
361
// Update the bundle per-machine/per-user scope based on the chained packages.
364
- this.ResolveBundleInstallScope(section, bundleSymbol, orderedFacades);
362
+ this.ResolveBundleInstallScope(section, bundleSymbol, facades.OrderedValues);
363
364
var softwareTags = section.Symbols.OfType<WixBundleTagSymbol>().ToList();
365
if (softwareTags.Any())
@@ -370,7 +368,7 @@ namespace WixToolset.Core.Burn
368
command.Execute();
369
}
370
373
- this.DetectDuplicateCacheIds(facades);
371
+ this.DetectDuplicateCacheIds(facades.Values);
372
373
if (this.Messaging.EncounteredError)
374
{
@@ -413,7 +411,7 @@ namespace WixToolset.Core.Burn
411
// Generate the core-defined BA manifest tables...
412
string baManifestPath;
413
{
416
- var command = new CreateBootstrapperApplicationManifestCommand(section, bundleSymbol, boundaries, orderedFacades, uxPayloadIndex, payloadSymbols, packagesPayloads, this.IntermediateFolder, this.InternalBurnBackendHelper);
414
+ var command = new CreateBootstrapperApplicationManifestCommand(section, bundleSymbol, boundaries, facades, uxPayloadIndex, payloadSymbols, packagesPayloads, this.IntermediateFolder, this.InternalBurnBackendHelper);
415
command.Execute();
416
417
var baManifestPayload = command.BootstrapperApplicationManifestPayloadRow;
@@ -480,7 +478,7 @@ namespace WixToolset.Core.Burn
478
{
479
var executableName = Path.GetFileName(this.OutputPath);
480
483
- var command = new CreateBurnManifestCommand(executableName, section, bundleSymbol, containers.Values, chainSymbol, orderedFacades, boundaries, uxPayloads, payloadSymbols, packagesPayloads, orderedSearches, this.IntermediateFolder);
481
+ var command = new CreateBurnManifestCommand(executableName, section, bundleSymbol, containers.Values, chainSymbol, facades, boundaries, uxPayloads, payloadSymbols, packagesPayloads, orderedSearches, this.IntermediateFolder);
482
command.Execute();
483
484
manifestPath = command.OutputPath;
@@ -637,11 +635,11 @@ namespace WixToolset.Core.Burn
635
}
636
}
637
640
- private void DetectDuplicateCacheIds(IDictionary<string, PackageFacade> facades)
638
+ private void DetectDuplicateCacheIds(IEnumerable<PackageFacade> facades)
639
{
640
var duplicateCacheIdDetector = new Dictionary<string, WixBundlePackageSymbol>();
641
644
- foreach (var facade in facades.Values)
642
+ foreach (var facade in facades)
643
{
644
if (duplicateCacheIdDetector.TryGetValue(facade.PackageSymbol.CacheId, out var collisionPackage))
645
{
src/wix/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs
+1
@@ -71,6 +71,7 @@ namespace WixToolset.Core.Burn.Bind
71
case SymbolDefinitionType.WixBundleExePackagePayload:
72
case SymbolDefinitionType.WixBundleExtension:
73
case SymbolDefinitionType.WixBundleHarvestedBundlePackage:
74
+ case SymbolDefinitionType.WixBundleHarvestedDependencyProvider:
75
case SymbolDefinitionType.WixBundleHarvestedMsiPackage:
76
case SymbolDefinitionType.WixBundleHarvestedMspPackage:
77
case SymbolDefinitionType.WixBundleMsiFeature:
src/wix/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs
+42
-7
@@ -12,11 +12,12 @@ namespace WixToolset.Core.Burn.Bind
12
13
internal class ProcessDependencyProvidersCommand
14
{
15
- public ProcessDependencyProvidersCommand(IMessaging messaging, IntermediateSection section, IDictionary<string, PackageFacade> facades)
15
+ public ProcessDependencyProvidersCommand(IServiceProvider serviceProvider, IntermediateSection section, PackageFacades facades)
16
{
17
- this.Messaging = messaging;
18
- this.Section = section;
17
+ this.Messaging = serviceProvider.GetService<IMessaging>();
18
+ this.BackendHelper = serviceProvider.GetService<IBackendHelper>();
19
20
+ this.Section = section;
21
this.Facades = facades;
22
}
23
@@ -24,9 +25,11 @@ namespace WixToolset.Core.Burn.Bind
25
26
private IMessaging Messaging { get; }
27
28
+ private IBackendHelper BackendHelper { get; }
29
+
30
private IntermediateSection Section { get; }
31
29
- private IDictionary<string, PackageFacade> Facades { get; }
32
+ private PackageFacades Facades { get; }
33
34
/// <summary>
35
/// Sets the explicitly provided bundle provider key, if provided. And...
@@ -36,23 +39,29 @@ namespace WixToolset.Core.Burn.Bind
39
/// </summary>
40
public void Execute()
41
{
42
+ this.ProcessHarvestedProviders();
43
+
44
var dependencySymbols = this.Section.Symbols.OfType<WixDependencyProviderSymbol>();
45
46
foreach (var dependency in dependencySymbols)
47
{
48
// Sets the provider key for the bundle, if it is not set already.
44
- if (String.IsNullOrEmpty(this.BundleProviderKey))
49
+ if (dependency.Bundle)
50
{
46
- if (dependency.Bundle)
51
+ if (String.IsNullOrEmpty(this.BundleProviderKey))
52
{
53
this.BundleProviderKey = dependency.ProviderKey;
54
}
55
+ else
56
+ {
57
+ this.Messaging.Write(BurnBackendErrors.BundleMultipleProviders(dependency.SourceLineNumbers, dependency.ProviderKey, this.BundleProviderKey));
58
+ }
59
}
60
61
// Import any authored dependencies. These may merge with imported provides from MSI packages.
62
var packageId = dependency.ParentRef;
63
55
- if (this.Facades.TryGetValue(packageId, out var facade))
64
+ if (this.Facades.TryGetFacadeByPackageId(packageId, out var facade))
65
{
66
if (String.IsNullOrEmpty(dependency.ProviderKey))
67
{
@@ -142,5 +151,31 @@ namespace WixToolset.Core.Burn.Bind
151
152
return dependencySymbolsByPackageId;
153
}
154
+
155
+ private void ProcessHarvestedProviders()
156
+ {
157
+ var harvestedDependencies = this.Section.Symbols.OfType<WixBundleHarvestedDependencyProviderSymbol>().ToList();
158
+ foreach (var harvestedDependency in harvestedDependencies)
159
+ {
160
+ if (!this.Facades.TryGetFacadesByPackagePayloadId(harvestedDependency.PackagePayloadRef, out var facades))
161
+ {
162
+ this.Messaging.Write(ErrorMessages.IdentifierNotFound("Package.PayloadRef", harvestedDependency.PackagePayloadRef));
163
+ continue;
164
+ }
165
+
166
+ foreach (var facade in facades)
167
+ {
168
+ var depId = new Identifier(AccessModifier.Section, this.BackendHelper.GenerateIdentifier("dep", facade.PackageId, harvestedDependency.Id.Id));
169
+ this.Section.AddSymbol(new WixDependencyProviderSymbol(harvestedDependency.SourceLineNumbers, depId)
170
+ {
171
+ ParentRef = facade.PackageId,
172
+ ProviderKey = harvestedDependency.ProviderKey,
173
+ Version = harvestedDependency.Version,
174
+ DisplayName = harvestedDependency.DisplayName,
175
+ Attributes = WixDependencyProviderAttributes.ProvidesAttributesImported | (WixDependencyProviderAttributes)harvestedDependency.ProviderAttributes,
176
+ });
177
+ }
178
+ }
179
+ }
180
}
181
}
src/wix/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs
+24
-15
@@ -7,18 +7,22 @@ namespace WixToolset.Core.Burn.Bundles
7
using System.Linq;
8
using WixToolset.Data;
9
using WixToolset.Data.Symbols;
10
+ using WixToolset.Extensibility.Services;
11
12
internal class AutomaticallySlipstreamPatchesCommand
13
{
13
- public AutomaticallySlipstreamPatchesCommand(IntermediateSection section, ICollection<PackageFacade> packageFacades)
14
+ public AutomaticallySlipstreamPatchesCommand(IMessaging messaging, IntermediateSection section, PackageFacades packageFacades)
15
{
16
+ this.Messaging = messaging;
17
this.Section = section;
18
this.PackageFacades = packageFacades;
19
}
20
21
+ private IMessaging Messaging { get; }
22
+
23
private IntermediateSection Section { get; }
24
21
- private IEnumerable<PackageFacade> PackageFacades { get; }
25
+ private PackageFacades PackageFacades { get; }
26
27
public void Execute()
28
{
@@ -26,7 +30,7 @@ namespace WixToolset.Core.Burn.Bundles
30
var targetsProductCode = new Dictionary<string, List<WixBundlePatchTargetCodeSymbol>>();
31
var targetsUpgradeCode = new Dictionary<string, List<WixBundlePatchTargetCodeSymbol>>();
32
29
- foreach (var facade in this.PackageFacades)
33
+ foreach (var facade in this.PackageFacades.Values)
34
{
35
// Keep track of all MSI packages.
36
if (facade.SpecificPackageSymbol is WixBundleMsiPackageSymbol msiPackage)
@@ -37,7 +41,7 @@ namespace WixToolset.Core.Burn.Bundles
41
{
42
var patchTargetCodeSymbols = this.Section.Symbols
43
.OfType<WixBundlePatchTargetCodeSymbol>()
40
- .Where(r => r.PackageRef == facade.PackageId);
44
+ .Where(r => r.PackagePayloadRef == facade.PackageSymbol.PayloadRef);
45
46
// Index target ProductCodes and UpgradeCodes for slipstreamed MSPs.
47
foreach (var symbol in patchTargetCodeSymbols)
@@ -89,22 +93,27 @@ namespace WixToolset.Core.Burn.Bundles
93
}
94
}
95
92
- private bool TryAddSlipstreamSymbol(HashSet<string> slipstreamMspIds, WixBundleMsiPackageSymbol msiPackage, WixBundlePatchTargetCodeSymbol patchTargetCode)
96
+ private void TryAddSlipstreamSymbol(HashSet<string> slipstreamMspIds, WixBundleMsiPackageSymbol msiPackage, WixBundlePatchTargetCodeSymbol patchTargetCode)
97
{
94
- var id = new Identifier(AccessModifier.Section, msiPackage.Id.Id, patchTargetCode.PackageRef);
98
+ if (!this.PackageFacades.TryGetFacadesByPackagePayloadId(patchTargetCode.PackagePayloadRef, out var packageFacades))
99
+ {
100
+ this.Messaging.Write(ErrorMessages.IdentifierNotFound("Package.PayloadRef", patchTargetCode.PackagePayloadRef));
101
+ return;
102
+ }
103
96
- if (slipstreamMspIds.Add(id.Id))
104
+ foreach (var packageFacade in packageFacades)
105
{
98
- this.Section.AddSymbol(new WixBundleSlipstreamMspSymbol(patchTargetCode.SourceLineNumbers)
99
- {
100
- TargetPackageRef = msiPackage.Id.Id,
101
- MspPackageRef = patchTargetCode.PackageRef,
102
- });
106
+ var id = new Identifier(AccessModifier.Section, msiPackage.Id.Id, packageFacade.PackageId);
107
104
- return true;
108
+ if (slipstreamMspIds.Add(id.Id))
109
+ {
110
+ this.Section.AddSymbol(new WixBundleSlipstreamMspSymbol(patchTargetCode.SourceLineNumbers)
111
+ {
112
+ TargetPackageRef = msiPackage.Id.Id,
113
+ MspPackageRef = packageFacade.PackageId,
114
+ });
115
+ }
116
}
106
-
107
- return false;
117
}
118
}
119
}
src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
+37
-24
@@ -15,12 +15,12 @@ namespace WixToolset.Core.Burn.Bundles
15
16
internal class CreateBootstrapperApplicationManifestCommand
17
{
18
- public CreateBootstrapperApplicationManifestCommand(IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<WixBundleRollbackBoundarySymbol> boundaries, IEnumerable<PackageFacade> chainPackages, int lastUXPayloadIndex, Dictionary<string, WixBundlePayloadSymbol> payloadSymbols, Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> packagesPayloads, string intermediateFolder, IInternalBurnBackendHelper internalBurnBackendHelper)
18
+ public CreateBootstrapperApplicationManifestCommand(IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<WixBundleRollbackBoundarySymbol> boundaries, PackageFacades packageFacades, 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.RollbackBoundaries = boundaries;
23
- this.ChainPackages = chainPackages;
23
+ this.PackagesFacades = packageFacades;
24
this.LastUXPayloadIndex = lastUXPayloadIndex;
25
this.Payloads = payloadSymbols;
26
this.PackagesPayloads = packagesPayloads;
@@ -34,7 +34,7 @@ namespace WixToolset.Core.Burn.Bundles
34
35
private IEnumerable<WixBundleRollbackBoundarySymbol> RollbackBoundaries { get; }
36
37
- private IEnumerable<PackageFacade> ChainPackages { get; }
37
+ private PackageFacades PackagesFacades { get; }
38
39
private IInternalBurnBackendHelper InternalBurnBackendHelper { get; }
40
@@ -141,7 +141,7 @@ namespace WixToolset.Core.Burn.Bundles
141
142
private void WritePackageInfo(XmlTextWriter writer)
143
{
144
- foreach (var package in this.ChainPackages)
144
+ foreach (var package in this.PackagesFacades.OrderedValues)
145
{
146
if (!this.PackagesPayloads.TryGetValue(package.PackageId, out var payloads))
147
{
@@ -229,33 +229,46 @@ namespace WixToolset.Core.Burn.Bundles
229
230
foreach (var featureSymbol in featureSymbols)
231
{
232
- writer.WriteStartElement("WixPackageFeatureInfo");
233
-
234
- writer.WriteAttributeString("Package", featureSymbol.PackageRef);
235
- writer.WriteAttributeString("Feature", featureSymbol.Name);
236
- writer.WriteAttributeString("Size", featureSymbol.Size.ToString(CultureInfo.InvariantCulture));
237
-
238
- if (!String.IsNullOrEmpty(featureSymbol.Parent))
232
+ if (!this.PackagesFacades.TryGetFacadesByPackagePayloadId(featureSymbol.PackagePayloadRef, out var facades))
233
{
240
- writer.WriteAttributeString("Parent", featureSymbol.Parent);
234
+ continue;
235
}
236
243
- if (!String.IsNullOrEmpty(featureSymbol.Title))
237
+ foreach (var facade in facades)
238
{
245
- writer.WriteAttributeString("Title", featureSymbol.Title);
246
- }
239
+ if (!(facade.SpecificPackageSymbol is WixBundleMsiPackageSymbol msiPackage) || !msiPackage.EnableFeatureSelection)
240
+ {
241
+ continue;
242
+ }
243
248
- if (!String.IsNullOrEmpty(featureSymbol.Description))
249
- {
250
- writer.WriteAttributeString("Description", featureSymbol.Description);
251
- }
244
+ writer.WriteStartElement("WixPackageFeatureInfo");
245
253
- writer.WriteAttributeString("Display", featureSymbol.Display.ToString(CultureInfo.InvariantCulture));
254
- writer.WriteAttributeString("Level", featureSymbol.Level.ToString(CultureInfo.InvariantCulture));
255
- writer.WriteAttributeString("Directory", featureSymbol.Directory);
256
- writer.WriteAttributeString("Attributes", featureSymbol.Attributes.ToString(CultureInfo.InvariantCulture));
246
+ writer.WriteAttributeString("Package", facade.PackageId);
247
+ writer.WriteAttributeString("Feature", featureSymbol.Name);
248
+ writer.WriteAttributeString("Size", featureSymbol.Size.ToString(CultureInfo.InvariantCulture));
249
258
- writer.WriteEndElement();
250
+ if (!String.IsNullOrEmpty(featureSymbol.Parent))
251
+ {
252
+ writer.WriteAttributeString("Parent", featureSymbol.Parent);
253
+ }
254
+
255
+ if (!String.IsNullOrEmpty(featureSymbol.Title))
256
+ {
257
+ writer.WriteAttributeString("Title", featureSymbol.Title);
258
+ }
259
+
260
+ if (!String.IsNullOrEmpty(featureSymbol.Description))
261
+ {
262
+ writer.WriteAttributeString("Description", featureSymbol.Description);
263
+ }
264
+
265
+ writer.WriteAttributeString("Display", featureSymbol.Display.ToString(CultureInfo.InvariantCulture));
266
+ writer.WriteAttributeString("Level", featureSymbol.Level.ToString(CultureInfo.InvariantCulture));
267
+ writer.WriteAttributeString("Directory", featureSymbol.Directory);
268
+ writer.WriteAttributeString("Attributes", featureSymbol.Attributes.ToString(CultureInfo.InvariantCulture));
269
+
270
+ writer.WriteEndElement();
271
+ }
272
}
273
}
274
src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
+27
-22
@@ -18,14 +18,14 @@ namespace WixToolset.Core.Burn.Bundles
18
19
internal class CreateBurnManifestCommand
20
{
21
- public CreateBurnManifestCommand(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)
21
+ public CreateBurnManifestCommand(string executableName, IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<WixBundleContainerSymbol> containers, WixChainSymbol chainSymbol, PackageFacades packageFacades, IEnumerable<WixBundleRollbackBoundarySymbol> boundaries, IEnumerable<WixBundlePayloadSymbol> uxPayloads, Dictionary<string, WixBundlePayloadSymbol> allPayloadsById, Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> packagesPayloads, IEnumerable<ISearchFacade> orderedSearches, string intermediateFolder)
22
{
23
this.ExecutableName = executableName;
24
this.Section = section;
25
this.BundleSymbol = bundleSymbol;
26
this.Chain = chainSymbol;
27
this.Containers = containers;
28
- this.OrderedPackages = orderedPackages;
28
+ this.PackageFacades = packageFacades;
29
this.RollbackBoundaries = boundaries;
30
this.UXContainerPayloads = uxPayloads;
31
this.Payloads = allPayloadsById;
@@ -46,7 +46,7 @@ namespace WixToolset.Core.Burn.Bundles
46
47
private IEnumerable<WixBundleRollbackBoundarySymbol> RollbackBoundaries { get; }
48
49
- private IEnumerable<PackageFacade> OrderedPackages { get; }
49
+ private PackageFacades PackageFacades { get; }
50
51
private IEnumerable<ISearchFacade> OrderedSearches { get; }
52
@@ -316,11 +316,11 @@ namespace WixToolset.Core.Burn.Bundles
316
}
317
318
// Index a few tables by package.
319
- var targetCodesByPatch = this.Section.Symbols.OfType<WixBundlePatchTargetCodeSymbol>().ToLookup(r => r.PackageRef);
320
- var msiFeaturesByPackage = this.Section.Symbols.OfType<WixBundleMsiFeatureSymbol>().ToLookup(r => r.PackageRef);
319
+ var targetCodesByPackagePayload = this.Section.Symbols.OfType<WixBundlePatchTargetCodeSymbol>().ToLookup(r => r.PackagePayloadRef);
320
+ var msiFeaturesByPackagePayload = this.Section.Symbols.OfType<WixBundleMsiFeatureSymbol>().ToLookup(r => r.PackagePayloadRef);
321
var msiPropertiesByPackage = this.Section.Symbols.OfType<WixBundleMsiPropertySymbol>().ToLookup(r => r.PackageRef);
322
- var relatedBundlesByPackage = this.Section.Symbols.OfType<WixBundlePackageRelatedBundleSymbol>().ToLookup(r => r.PackageRef);
323
- var relatedPackagesByPackage = this.Section.Symbols.OfType<WixBundleRelatedPackageSymbol>().ToLookup(r => r.PackageRef);
322
+ var relatedBundlesByPackagePayload = this.Section.Symbols.OfType<WixBundlePackageRelatedBundleSymbol>().ToLookup(r => r.PackagePayloadRef);
323
+ var relatedPackagesByPackagePayload = this.Section.Symbols.OfType<WixBundleRelatedPackageSymbol>().ToLookup(r => r.PackagePayloadRef);
324
var slipstreamMspsByPackage = this.Section.Symbols.OfType<WixBundleSlipstreamMspSymbol>().ToLookup(r => r.TargetPackageRef);
325
var exitCodesByPackage = this.Section.Symbols.OfType<WixBundlePackageExitCodeSymbol>().ToLookup(r => r.ChainPackageId);
326
var commandLinesByPackage = this.Section.Symbols.OfType<WixBundlePackageCommandLineSymbol>().ToLookup(r => r.WixBundlePackageRef);
@@ -331,8 +331,10 @@ namespace WixToolset.Core.Burn.Bundles
331
// Build up the list of target codes from all the MSPs in the chain.
332
var targetCodes = new List<WixBundlePatchTargetCodeSymbol>();
333
334
- foreach (var package in this.OrderedPackages)
334
+ foreach (var package in this.PackageFacades.OrderedValues)
335
{
336
+ var packagePayloadId = package.PackageSymbol.PayloadRef;
337
+
338
writer.WriteStartElement(String.Format(CultureInfo.InvariantCulture, "{0}Package", package.PackageSymbol.Type));
339
340
writer.WriteAttributeString("Id", package.PackageId);
@@ -425,6 +427,19 @@ namespace WixToolset.Core.Burn.Bundles
427
{
428
writer.WriteAttributeString("UpgradeCode", msiPackage.UpgradeCode);
429
}
430
+
431
+ // If feature selection is enabled, represent the Feature table in the manifest.
432
+ if (msiPackage.EnableFeatureSelection)
433
+ {
434
+ var packageMsiFeatures = msiFeaturesByPackagePayload[packagePayloadId];
435
+
436
+ foreach (var feature in packageMsiFeatures)
437
+ {
438
+ writer.WriteStartElement("MsiFeature");
439
+ writer.WriteAttributeString("Id", feature.Name);
440
+ writer.WriteEndElement();
441
+ }
442
+ }
443
}
444
else if (package.SpecificPackageSymbol is WixBundleMspPackageSymbol mspPackage) // MSP
445
{
@@ -435,7 +450,7 @@ namespace WixToolset.Core.Burn.Bundles
450
// product codes, add the patch list to the overall list.
451
if (null != targetCodes)
452
{
438
- foreach (var patchTargetCode in targetCodesByPatch[mspPackage.Id.Id])
453
+ foreach (var patchTargetCode in targetCodesByPackagePayload[packagePayloadId])
454
{
455
if (patchTargetCode.Type == WixBundlePatchTargetCodeType.Unspecified)
456
{
@@ -453,15 +468,6 @@ namespace WixToolset.Core.Burn.Bundles
468
writer.WriteAttributeString("KB", msuPackage.MsuKB);
469
}
470
456
- var packageMsiFeatures = msiFeaturesByPackage[package.PackageId];
457
-
458
- foreach (var feature in packageMsiFeatures)
459
- {
460
- writer.WriteStartElement("MsiFeature");
461
- writer.WriteAttributeString("Id", feature.Name);
462
- writer.WriteEndElement();
463
- }
464
-
471
var packageMsiProperties = msiPropertiesByPackage[package.PackageId];
472
473
foreach (var msiProperty in packageMsiProperties)
@@ -536,14 +542,14 @@ namespace WixToolset.Core.Burn.Bundles
542
543
if (dependency.Imported)
544
{
539
- // The package dependency was explicitly authored into the manifest.
545
+ // The package dependency was harvested from the package.
546
writer.WriteAttributeString("Imported", "yes");
547
}
548
549
writer.WriteEndElement();
550
}
551
546
- var packageRelatedBundles = relatedBundlesByPackage[package.PackageId];
552
+ var packageRelatedBundles = relatedBundlesByPackagePayload[packagePayloadId];
553
554
foreach (var relatedBundle in packageRelatedBundles)
555
{
@@ -553,7 +559,7 @@ namespace WixToolset.Core.Burn.Bundles
559
writer.WriteEndElement();
560
}
561
556
- var packageRelatedPackages = relatedPackagesByPackage[package.PackageId];
562
+ var packageRelatedPackages = relatedPackagesByPackagePayload[packagePayloadId];
563
564
foreach (var related in packageRelatedPackages)
565
{
@@ -587,7 +593,6 @@ namespace WixToolset.Core.Burn.Bundles
593
}
594
595
// Write any contained Payloads with the PackagePayload being first
590
- var packagePayloadId = package.PackageSymbol.PayloadRef;
596
writer.WriteStartElement("PayloadRef");
597
writer.WriteAttributeString("Id", packagePayloadId);
598
writer.WriteEndElement();
src/wix/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs
+8
-7
@@ -23,7 +23,7 @@ namespace WixToolset.Core.Burn.Bundles
23
24
private IntermediateSection Section { get; }
25
26
- public IDictionary<string, PackageFacade> PackageFacades { get; private set; }
26
+ public PackageFacades PackageFacades { get; private set; }
27
28
public void Execute()
29
{
@@ -39,7 +39,7 @@ namespace WixToolset.Core.Burn.Bundles
39
var mspPackagePayloads = this.Section.Symbols.OfType<WixBundleMspPackagePayloadSymbol>().ToDictionary(t => t.Id.Id);
40
var msuPackagePayloads = this.Section.Symbols.OfType<WixBundleMsuPackagePayloadSymbol>().ToDictionary(t => t.Id.Id);
41
42
- var facades = new Dictionary<string, PackageFacade>();
42
+ var facades = new PackageFacades();
43
44
foreach (var package in this.ChainPackageSymbols)
45
{
@@ -135,6 +135,7 @@ namespace WixToolset.Core.Burn.Bundles
135
if (packagePayload == null)
136
{
137
this.Messaging.Write(ErrorMessages.MissingPackagePayload(package.SourceLineNumbers, id, package.Type.ToString()));
138
+ continue;
139
}
140
else
141
{
@@ -146,7 +147,7 @@ namespace WixToolset.Core.Burn.Bundles
147
case WixBundlePackageType.Bundle:
148
if (bundlePackages.TryGetValue(id, out var bundlePackage))
149
{
149
- facades.Add(id, new PackageFacade(package, bundlePackage));
150
+ facades.Add(new PackageFacade(package, bundlePackage));
151
}
152
else
153
{
@@ -157,7 +158,7 @@ namespace WixToolset.Core.Burn.Bundles
158
case WixBundlePackageType.Exe:
159
if (exePackages.TryGetValue(id, out var exePackage))
160
{
160
- facades.Add(id, new PackageFacade(package, exePackage));
161
+ facades.Add(new PackageFacade(package, exePackage));
162
}
163
else
164
{
@@ -168,7 +169,7 @@ namespace WixToolset.Core.Burn.Bundles
169
case WixBundlePackageType.Msi:
170
if (msiPackages.TryGetValue(id, out var msiPackage))
171
{
171
- facades.Add(id, new PackageFacade(package, msiPackage));
172
+ facades.Add(new PackageFacade(package, msiPackage));
173
}
174
else
175
{
@@ -179,7 +180,7 @@ namespace WixToolset.Core.Burn.Bundles
180
case WixBundlePackageType.Msp:
181
if (mspPackages.TryGetValue(id, out var mspPackage))
182
{
182
- facades.Add(id, new PackageFacade(package, mspPackage));
183
+ facades.Add(new PackageFacade(package, mspPackage));
184
}
185
else
186
{
@@ -190,7 +191,7 @@ namespace WixToolset.Core.Burn.Bundles
191
case WixBundlePackageType.Msu:
192
if (msuPackages.TryGetValue(id, out var msuPackage))
193
{
193
- facades.Add(id, new PackageFacade(package, msuPackage));
194
+ facades.Add(new PackageFacade(package, msuPackage));
195
}
196
else
197
{
src/wix/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs
+5
-9
@@ -12,7 +12,7 @@ namespace WixToolset.Core.Burn.Bundles
12
13
internal class OrderPackagesAndRollbackBoundariesCommand
14
{
15
- public OrderPackagesAndRollbackBoundariesCommand(IMessaging messaging, IntermediateSection section, IDictionary<string, PackageFacade> packageFacades)
15
+ public OrderPackagesAndRollbackBoundariesCommand(IMessaging messaging, IntermediateSection section, PackageFacades packageFacades)
16
{
17
this.Messaging = messaging;
18
this.Section = section;
@@ -23,9 +23,7 @@ namespace WixToolset.Core.Burn.Bundles
23
24
private IntermediateSection Section { get; }
25
26
- private IDictionary<string, PackageFacade> PackageFacades { get; }
27
-
28
- public IEnumerable<PackageFacade> OrderedPackageFacades { get; private set; }
26
+ private PackageFacades PackageFacades { get; }
27
28
public IEnumerable<WixBundleRollbackBoundarySymbol> UsedRollbackBoundaries { get; private set; }
29
@@ -34,7 +32,6 @@ namespace WixToolset.Core.Burn.Bundles
32
var groupSymbols = this.Section.Symbols.OfType<WixGroupSymbol>().ToList();
33
var boundariesById = this.Section.Symbols.OfType<WixBundleRollbackBoundarySymbol>().ToDictionary(b => b.Id.Id);
34
37
- var orderedFacades = new List<PackageFacade>();
35
var usedBoundaries = new List<WixBundleRollbackBoundarySymbol>();
36
37
// Process the chain of packages to add them in the correct order
@@ -55,7 +52,7 @@ namespace WixToolset.Core.Burn.Bundles
52
{
53
if (ComplexReferenceChildType.Package == groupSymbol.ChildType && ComplexReferenceParentType.PackageGroup == groupSymbol.ParentType && BurnConstants.BundleChainPackageGroupId == groupSymbol.ParentId)
54
{
58
- if (this.PackageFacades.TryGetValue(groupSymbol.ChildId, out var facade))
55
+ if (this.PackageFacades.TryGetFacadeByPackageId(groupSymbol.ChildId, out var facade))
56
{
57
var insideMsiTransaction = lastRollbackBoundary.Transaction;
58
@@ -102,7 +99,7 @@ namespace WixToolset.Core.Burn.Bundles
99
}
100
}
101
105
- orderedFacades.Add(facade);
102
+ this.PackageFacades.AddOrdered(facade);
103
}
104
else // must be a rollback boundary.
105
{
@@ -158,7 +155,7 @@ namespace WixToolset.Core.Burn.Bundles
155
string previousRollbackBoundaryId = null;
156
PackageFacade previousFacade = null;
157
161
- foreach (var package in orderedFacades)
158
+ foreach (var package in this.PackageFacades.OrderedValues)
159
{
160
if (null != package.PackageSymbol.RollbackBoundaryRef)
161
{
@@ -178,7 +175,6 @@ namespace WixToolset.Core.Burn.Bundles
175
previousFacade.PackageSymbol.RollbackBoundaryBackwardRef = previousRollbackBoundaryId;
176
}
177
181
- this.OrderedPackageFacades = orderedFacades;
178
this.UsedRollbackBoundaries = usedBoundaries;
179
}
180
}
src/wix/WixToolset.Core.Burn/Bundles/PackageFacades.cs
new
+54
@@ -0,0 +1,54 @@
1
+// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
+
3
+namespace WixToolset.Core.Burn.Bundles
4
+{
5
+ using System.Collections.Generic;
6
+ using System.Linq;
7
+ using WixToolset.Data;
8
+
9
+ internal class PackageFacades
10
+ {
11
+ private Dictionary<string, PackageFacade> FacadesByPackageId { get; } = new Dictionary<string, PackageFacade>();
12
+
13
+ private Dictionary<string, List<PackageFacade>> FacadesByPackagePayloadId { get; } = new Dictionary<string, List<PackageFacade>>();
14
+
15
+ private List<PackageFacade> OrderedFacades { get; } = new List<PackageFacade>();
16
+
17
+ public void Add(PackageFacade item)
18
+ {
19
+ this.FacadesByPackageId.Add(item.PackageId, item);
20
+
21
+ if (!this.FacadesByPackagePayloadId.TryGetValue(item.PackageSymbol.PayloadRef, out var facades))
22
+ {
23
+ facades = new List<PackageFacade>();
24
+ this.FacadesByPackagePayloadId.Add(item.PackageSymbol.PayloadRef, facades);
25
+ }
26
+
27
+ facades.Add(item);
28
+ }
29
+
30
+ public void AddOrdered(PackageFacade item)
31
+ {
32
+ if (!this.FacadesByPackageId.ContainsKey(item.PackageId))
33
+ {
34
+ throw new WixException("Ordered PackageFacade must already exist");
35
+ }
36
+
37
+ this.OrderedFacades.Add(item);
38
+ }
39
+
40
+ public IReadOnlyCollection<PackageFacade> OrderedValues => this.OrderedFacades.AsReadOnly();
41
+
42
+ public IEnumerable<PackageFacade> Values => this.FacadesByPackageId.Values;
43
+
44
+ public bool TryGetFacadeByPackageId(string packageId, out PackageFacade facade)
45
+ {
46
+ return this.FacadesByPackageId.TryGetValue(packageId, out facade);
47
+ }
48
+
49
+ public bool TryGetFacadesByPackagePayloadId(string packagePayloadId, out List<PackageFacade> facades)
50
+ {
51
+ return this.FacadesByPackagePayloadId.TryGetValue(packagePayloadId, out facades);
52
+ }
53
+ }
54
+}
src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs
+4
-5
@@ -3,7 +3,6 @@
3
namespace WixToolset.Core.Burn.Bundles
4
{
5
using System;
6
- using System.Collections.Generic;
6
using WixToolset.Data;
7
using WixToolset.Data.Symbols;
8
using WixToolset.Extensibility.Data;
@@ -11,12 +10,12 @@ namespace WixToolset.Core.Burn.Bundles
10
11
internal class PerformBundleBackendValidationCommand
12
{
14
- public PerformBundleBackendValidationCommand(IMessaging messaging, IBurnBackendHelper burnBackendHelper, IntermediateSection section, IDictionary<string, PackageFacade> packageFacadesById)
13
+ public PerformBundleBackendValidationCommand(IMessaging messaging, IBurnBackendHelper burnBackendHelper, IntermediateSection section, PackageFacades packageFacades)
14
{
15
this.Messaging = messaging;
16
this.BackendHelper = burnBackendHelper;
17
this.Section = section;
19
- this.PackageFacadesById = packageFacadesById;
18
+ this.PackageFacades = packageFacades;
19
}
20
21
private IMessaging Messaging { get; }
@@ -25,7 +24,7 @@ namespace WixToolset.Core.Burn.Bundles
24
25
private IntermediateSection Section { get; }
26
28
- private IDictionary<string, PackageFacade> PackageFacadesById { get; }
27
+ private PackageFacades PackageFacades { get; }
28
29
public void Execute()
30
{
@@ -53,7 +52,7 @@ namespace WixToolset.Core.Burn.Bundles
52
}
53
}
54
56
- foreach (var packageFacade in this.PackageFacadesById.Values)
55
+ foreach (var packageFacade in this.PackageFacades.Values)
56
{
57
if (packageFacade.SpecificPackageSymbol is WixBundleBundlePackageSymbol wixBundleBundlePackageSymbol)
58
{
src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs
+7
-8
@@ -57,8 +57,8 @@ namespace WixToolset.Core.Burn.Bundles
57
public void Execute()
58
{
59
var harvestedBundlePackage = this.Section.Symbols.OfType<WixBundleHarvestedBundlePackageSymbol>()
60
- .Where(h => h.Id == this.ChainPackage.Id)
61
- .SingleOrDefault();
60
+ .Where(h => h.Id == this.PackagePayload.Id)
61
+ .SingleOrDefault();
62
63
if (harvestedBundlePackage == null)
64
{
@@ -200,13 +200,12 @@ namespace WixToolset.Core.Burn.Bundles
200
version = registrationElement.GetAttribute("Version");
201
202
var providerKey = registrationElement.GetAttribute("ProviderKey");
203
- var depId = new Identifier(AccessModifier.Section, this.BackendHelper.GenerateIdentifier("dep", this.PackageId, providerKey));
204
- this.Section.AddSymbol(new WixDependencyProviderSymbol(sourceLineNumbers, depId)
203
+ var depId = new Identifier(AccessModifier.Section, this.BackendHelper.GenerateIdentifier("dep", this.PackagePayload.Id.Id, providerKey));
204
+ this.Section.AddSymbol(new WixBundleHarvestedDependencyProviderSymbol(sourceLineNumbers, depId)
205
{
206
- ParentRef = this.PackageId,
206
+ PackagePayloadRef = this.PackagePayload.Id.Id,
207
ProviderKey = providerKey,
208
Version = version,
209
- Attributes = WixDependencyProviderAttributes.ProvidesAttributesImported,
209
});
210
211
displayName = arpElement.GetAttribute("DisplayName");
@@ -224,7 +223,7 @@ namespace WixToolset.Core.Burn.Bundles
223
}
224
}
225
227
- return this.Section.AddSymbol(new WixBundleHarvestedBundlePackageSymbol(this.PackagePayload.SourceLineNumbers, this.ChainPackage.Id)
226
+ return this.Section.AddSymbol(new WixBundleHarvestedBundlePackageSymbol(this.PackagePayload.SourceLineNumbers, this.PackagePayload.Id)
227
{
228
Win64 = win64,
229
BundleId = bundleId,
@@ -274,7 +273,7 @@ namespace WixToolset.Core.Burn.Bundles
273
274
this.Section.AddSymbol(new WixBundlePackageRelatedBundleSymbol(sourceLineNumbers)
275
{
277
- PackageRef = this.PackageId,
276
+ PackagePayloadRef = this.PackagePayload.Id.Id,
277
BundleId = id,
278
Action = action,
279
});
src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
+21
-30
@@ -65,7 +65,7 @@ namespace WixToolset.Core.Burn.Bundles
65
public void Execute()
66
{
67
var harvestedMsiPackage = this.Section.Symbols.OfType<WixBundleHarvestedMsiPackageSymbol>()
68
- .Where(h => h.Id == this.ChainPackage.Id)
68
+ .Where(h => h.Id == this.PackagePayload.Id)
69
.SingleOrDefault();
70
71
if (harvestedMsiPackage == null)
@@ -78,6 +78,17 @@ namespace WixToolset.Core.Burn.Bundles
78
}
79
}
80
81
+ foreach (var childPayload in this.Section.Symbols.OfType<WixBundlePayloadSymbol>().Where(p => p.ParentPackagePayloadRef == this.PackagePayload.Id.Id).ToList())
82
+ {
83
+ this.Section.AddSymbol(new WixGroupSymbol(childPayload.SourceLineNumbers)
84
+ {
85
+ ParentType = ComplexReferenceParentType.Package,
86
+ ParentId = this.PackageId,
87
+ ChildType = ComplexReferenceChildType.Payload,
88
+ ChildId = childPayload.Id.Id,
89
+ });
90
+ }
91
+
92
this.ChainPackage.PerMachine = harvestedMsiPackage.PerMachine;
93
this.ChainPackage.Win64 = harvestedMsiPackage.Win64;
94
@@ -218,11 +229,7 @@ namespace WixToolset.Core.Burn.Bundles
229
230
this.CreateRelatedPackages(db);
231
221
- // If feature selection is enabled, represent the Feature table in the manifest.
222
- if (this.MsiPackage.EnableFeatureSelection)
223
- {
224
- this.CreateMsiFeatures(db);
225
- }
232
+ this.CreateMsiFeatures(db);
233
234
// Add all external cabinets as package payloads.
235
this.ImportExternalCabinetAsPayloads(db, payloadNames);
@@ -241,7 +248,7 @@ namespace WixToolset.Core.Burn.Bundles
248
return null;
249
}
250
244
- return this.Section.AddSymbol(new WixBundleHarvestedMsiPackageSymbol(this.PackagePayload.SourceLineNumbers, this.ChainPackage.Id)
251
+ return this.Section.AddSymbol(new WixBundleHarvestedMsiPackageSymbol(this.PackagePayload.SourceLineNumbers, this.PackagePayload.Id)
252
{
253
PerMachine = perMachine,
254
Win64 = win64,
@@ -379,7 +386,7 @@ namespace WixToolset.Core.Burn.Bundles
386
387
this.Section.AddSymbol(new WixBundleRelatedPackageSymbol(this.PackagePayload.SourceLineNumbers)
388
{
382
- PackageRef = this.PackageId,
389
+ PackagePayloadRef = this.PackagePayload.Id.Id,
390
RelatedId = record.GetString(1),
391
MinVersion = record.GetString(2),
392
MaxVersion = record.GetString(3),
@@ -425,9 +432,9 @@ namespace WixToolset.Core.Burn.Bundles
432
}
433
}
434
428
- this.Section.AddSymbol(new WixBundleMsiFeatureSymbol(this.PackagePayload.SourceLineNumbers, new Identifier(AccessModifier.Section, this.PackageId, featureName))
435
+ this.Section.AddSymbol(new WixBundleMsiFeatureSymbol(this.PackagePayload.SourceLineNumbers, new Identifier(AccessModifier.Section, this.PackagePayload.Id.Id, featureName))
436
{
430
- PackageRef = this.PackageId,
437
+ PackagePayloadRef = this.PackagePayload.Id.Id,
438
Name = featureName,
439
Parent = allFeaturesResultRecord.GetString(2),
440
Title = allFeaturesResultRecord.GetString(3),
@@ -468,14 +475,6 @@ namespace WixToolset.Core.Burn.Bundles
475
var generatedId = this.BackendHelper.GenerateIdentifier("cab", this.PackagePayload.Id.Id, cabinet);
476
var payloadSourceFile = this.ResolveRelatedFile(this.PackagePayload.SourceFile.Path, this.PackagePayload.UnresolvedSourceFile, cabinet, "Cabinet", sourceLineNumbers);
477
471
- this.Section.AddSymbol(new WixGroupSymbol(sourceLineNumbers)
472
- {
473
- ParentType = ComplexReferenceParentType.Package,
474
- ParentId = this.PackageId,
475
- ChildType = ComplexReferenceChildType.Payload,
476
- ChildId = generatedId
477
- });
478
-
478
this.Section.AddSymbol(new WixBundlePayloadSymbol(sourceLineNumbers, new Identifier(AccessModifier.Section, generatedId))
479
{
480
Name = cabinetName,
@@ -540,14 +539,6 @@ namespace WixToolset.Core.Burn.Bundles
539
var generatedId = this.BackendHelper.GenerateIdentifier("f", this.PackagePayload.Id.Id, record.GetString(2));
540
var payloadSourceFile = this.ResolveRelatedFile(this.PackagePayload.SourceFile.Path, this.PackagePayload.UnresolvedSourceFile, fileSourcePath, "File", sourceLineNumbers);
541
543
- this.Section.AddSymbol(new WixGroupSymbol(sourceLineNumbers)
544
- {
545
- ParentType = ComplexReferenceParentType.Package,
546
- ParentId = this.PackageId,
547
- ChildType = ComplexReferenceChildType.Payload,
548
- ChildId = generatedId
549
- });
550
-
542
this.Section.AddSymbol(new WixBundlePayloadSymbol(sourceLineNumbers, new Identifier(AccessModifier.Section, generatedId))
543
{
544
Name = name,
@@ -594,16 +585,16 @@ namespace WixToolset.Core.Burn.Bundles
585
{
586
foreach (var record in view.Records)
587
{
597
- var id = new Identifier(AccessModifier.Section, this.BackendHelper.GenerateIdentifier("dep", this.PackageId, record.GetString(1)));
588
+ var id = new Identifier(AccessModifier.Section, this.BackendHelper.GenerateIdentifier("dep", this.PackagePayload.Id.Id, record.GetString(1)));
589
590
// Import the provider key and attributes.
600
- this.Section.AddSymbol(new WixDependencyProviderSymbol(this.PackagePayload.SourceLineNumbers, id)
591
+ this.Section.AddSymbol(new WixBundleHarvestedDependencyProviderSymbol(this.PackagePayload.SourceLineNumbers, id)
592
{
602
- ParentRef = this.PackageId,
593
+ PackagePayloadRef = this.PackagePayload.Id.Id,
594
ProviderKey = record.GetString(2),
595
Version = record.GetString(3) ?? this.MsiPackage.ProductVersion,
596
DisplayName = record.GetString(4) ?? this.ChainPackage.DisplayName,
606
- Attributes = WixDependencyProviderAttributes.ProvidesAttributesImported | (WixDependencyProviderAttributes)record.GetInteger(5),
597
+ ProviderAttributes = record.GetInteger(5),
598
});
599
}
600
}
src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs
+3
-3
@@ -53,7 +53,7 @@ namespace WixToolset.Core.Burn.Bundles
53
public void Execute()
54
{
55
var harvestedMspPackage = this.Section.Symbols.OfType<WixBundleHarvestedMspPackageSymbol>()
56
- .Where(h => h.Id == this.ChainPackage.Id)
56
+ .Where(h => h.Id == this.PackagePayload.Id)
57
.SingleOrDefault();
58
59
if (harvestedMspPackage == null)
@@ -123,7 +123,7 @@ namespace WixToolset.Core.Burn.Bundles
123
return null;
124
}
125
126
- return this.Section.AddSymbol(new WixBundleHarvestedMspPackageSymbol(this.PackagePayload.SourceLineNumbers, this.ChainPackage.Id)
126
+ return this.Section.AddSymbol(new WixBundleHarvestedMspPackageSymbol(this.PackagePayload.SourceLineNumbers, this.PackagePayload.Id)
127
{
128
PatchCode = patchCode,
129
DisplayName = displayName,
@@ -175,7 +175,7 @@ namespace WixToolset.Core.Burn.Bundles
175
{
176
var symbol = section.AddSymbol(new WixBundlePatchTargetCodeSymbol(sourceLineNumbers)
177
{
178
- PackageRef = id.Id,
178
+ PackagePayloadRef = id.Id,
179
TargetCode = targetCode,
180
Attributes = 0,
181
Type = type,
src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs
+6
@@ -17,6 +17,11 @@ namespace WixToolset.Core.Burn
17
return Message(sourceLineNumbers, Ids.BAContainerPayloadCollision2, "The location of the payload related to the previous error.");
18
}
19
20
+ public static Message BundleMultipleProviders(SourceLineNumber sourceLineNumbers, string extraProviderKey, string originalProviderKey)
21
+ {
22
+ return Message(sourceLineNumbers, Ids.BundleMultipleProviders, "The bundle can only have a single dependency provider, but it has '{0}' and '{1}'.", originalProviderKey, extraProviderKey);
23
+ }
24
+
25
public static Message DuplicateCacheIds(SourceLineNumber originalLineNumber, string cacheId, string packageId)
26
{
27
return Message(originalLineNumber, Ids.DuplicateCacheIds, "The CacheId '{0}' for package '{1}' is duplicated. Each package must have a unique CacheId.", cacheId, packageId);
@@ -110,6 +115,7 @@ namespace WixToolset.Core.Burn
115
UnsupportedRemotePackagePayload = 8010,
116
FailedToAddIconOrSplashScreenToBundle = 8011,
117
InvalidBundleManifest = 8012,
118
+ BundleMultipleProviders = 8013,
119
} // last available is 8499. 8500 is BurnBackendWarnings.
120
}
121
}
src/wix/test/WixToolsetTest.CoreIntegration/PackagePayloadFixture.cs
+78
@@ -5,12 +5,90 @@ namespace WixToolsetTest.CoreIntegration
5
using System.Collections.Generic;
6
using System.IO;
7
using System.Linq;
8
+ using System.Xml;
9
using WixBuildTools.TestSupport;
10
using WixToolset.Core.TestPackage;
11
using Xunit;
12
13
public class PackagePayloadFixture
14
{
15
+ [Fact]
16
+ public void CanSpecifyMsiPackagePayloadInPayloadGroup()
17
+ {
18
+ var folder = TestData.Get(@"TestData");
19
+
20
+ using (var fs = new DisposableFileSystem())
21
+ {
22
+ var baseFolder = fs.GetFolder();
23
+ var intermediateFolder = Path.Combine(baseFolder, "obj");
24
+ var bundlePath = Path.Combine(baseFolder, @"bin\test.exe");
25
+ var baFolderPath = Path.Combine(baseFolder, "ba");
26
+ var extractFolderPath = Path.Combine(baseFolder, "extract");
27
+
28
+ var result = WixRunner.Execute(new[]
29
+ {
30
+ "build",
31
+ Path.Combine(folder, "PackagePayload", "MsiPackagePayloadInPayloadGroup.wxs"),
32
+ Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
33
+ "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
34
+ "-bindpath", Path.Combine(folder, ".Data"),
35
+ "-intermediateFolder", intermediateFolder,
36
+ "-o", bundlePath,
37
+ });
38
+
39
+ result.AssertSuccess();
40
+
41
+ Assert.True(File.Exists(bundlePath));
42
+
43
+ var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath);
44
+ extractResult.AssertSuccess();
45
+
46
+ var ignoreAttributesByElementName = new Dictionary<string, List<string>>
47
+ {
48
+ { "ExePackage", new List<string> { "CacheId", "InstallSize", "Size" } },
49
+ };
50
+ var msiPackageElements = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Chain/burn:MsiPackage")
51
+ .Cast<XmlElement>()
52
+ .Select(e => e.GetTestXml(ignoreAttributesByElementName))
53
+ .ToArray();
54
+ WixAssert.CompareLineByLine(new[]
55
+ {
56
+ "<MsiPackage Id='MsiWithFeatures' Cache='keep' CacheId='{040011E1-F84C-4927-AD62-50A5EC19CA32}v1.0.0.0_1' InstallSize='34' Size='32803' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryForward='WixDefaultBoundary' LogPathVariable='WixBundleLog_MsiWithFeatures' RollbackLogPathVariable='WixBundleRollbackLog_MsiWithFeatures' ProductCode='{040011E1-F84C-4927-AD62-50A5EC19CA32}' Language='1033' Version='1.0.0.0' UpgradeCode='{047730A5-30FE-4A62-A520-DA9381B8226A}'>" +
57
+ "<MsiFeature Id='ProductFeature' /><MsiProperty Id='ARPSYSTEMCOMPONENT' Value='1' /><MsiProperty Id='MSIFASTINSTALL' Value='7' /><Provides Key='{040011E1-F84C-4927-AD62-50A5EC19CA32}_v1.0.0.0' Version='1.0.0.0' DisplayName='MsiPackage' />" +
58
+ "<RelatedPackage Id='{047730A5-30FE-4A62-A520-DA9381B8226A}' MaxVersion='1.0.0.0' MaxInclusive='no' OnlyDetect='no' LangInclusive='yes'><Language Id='1033' /></RelatedPackage>" +
59
+ "<RelatedPackage Id='{047730A5-30FE-4A62-A520-DA9381B8226A}' MinVersion='1.0.0.0' MinInclusive='no' OnlyDetect='yes' LangInclusive='yes'><Language Id='1033' /></RelatedPackage>" +
60
+ "<PayloadRef Id='test.msi' /><PayloadRef Id='fhuZsOcBDTuIX8rF96kswqI6SnuI' /><PayloadRef Id='faf_OZ741BG7SJ6ZkcIvivZ2Yzo8' />" +
61
+ "</MsiPackage>",
62
+
63
+ "<MsiPackage Id='MsiWithoutFeatures' Cache='keep' CacheId='{040011E1-F84C-4927-AD62-50A5EC19CA32}v1.0.0.0_2' InstallSize='34' Size='32803' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryBackward='WixDefaultBoundary' LogPathVariable='WixBundleLog_MsiWithoutFeatures' RollbackLogPathVariable='WixBundleRollbackLog_MsiWithoutFeatures' ProductCode='{040011E1-F84C-4927-AD62-50A5EC19CA32}' Language='1033' Version='1.0.0.0' UpgradeCode='{047730A5-30FE-4A62-A520-DA9381B8226A}'>" +
64
+ "<MsiProperty Id='ARPSYSTEMCOMPONENT' Value='1' /><MsiProperty Id='MSIFASTINSTALL' Value='7' /><Provides Key='{040011E1-F84C-4927-AD62-50A5EC19CA32}_v1.0.0.0' Version='1.0.0.0' DisplayName='MsiPackage' />" +
65
+ "<RelatedPackage Id='{047730A5-30FE-4A62-A520-DA9381B8226A}' MaxVersion='1.0.0.0' MaxInclusive='no' OnlyDetect='no' LangInclusive='yes'><Language Id='1033' /></RelatedPackage>" +
66
+ "<RelatedPackage Id='{047730A5-30FE-4A62-A520-DA9381B8226A}' MinVersion='1.0.0.0' MinInclusive='no' OnlyDetect='yes' LangInclusive='yes'><Language Id='1033' /></RelatedPackage>" +
67
+ "<PayloadRef Id='test.msi' /><PayloadRef Id='fhuZsOcBDTuIX8rF96kswqI6SnuI' /><PayloadRef Id='faf_OZ741BG7SJ6ZkcIvivZ2Yzo8' />" +
68
+ "</MsiPackage>",
69
+ }, msiPackageElements);
70
+
71
+ var packageElements = extractResult.SelectBADataNodes("/ba:BootstrapperApplicationData/ba:WixPackageProperties")
72
+ .Cast<XmlElement>()
73
+ .Select(e => e.GetTestXml())
74
+ .ToArray();
75
+ WixAssert.CompareLineByLine(new []
76
+ {
77
+ "<WixPackageProperties Package='MsiWithFeatures' Vital='yes' DisplayName='MsiPackage' DownloadSize='32803' PackageSize='32803' InstalledSize='34' PackageType='Msi' Permanent='no' LogPathVariable='WixBundleLog_MsiWithFeatures' RollbackLogPathVariable='WixBundleRollbackLog_MsiWithFeatures' Compressed='yes' ProductCode='{040011E1-F84C-4927-AD62-50A5EC19CA32}' UpgradeCode='{047730A5-30FE-4A62-A520-DA9381B8226A}' Version='1.0.0.0' Cache='keep' />",
78
+ "<WixPackageProperties Package='MsiWithoutFeatures' Vital='yes' DisplayName='MsiPackage' DownloadSize='32803' PackageSize='32803' InstalledSize='34' PackageType='Msi' Permanent='no' LogPathVariable='WixBundleLog_MsiWithoutFeatures' RollbackLogPathVariable='WixBundleRollbackLog_MsiWithoutFeatures' Compressed='yes' ProductCode='{040011E1-F84C-4927-AD62-50A5EC19CA32}' UpgradeCode='{047730A5-30FE-4A62-A520-DA9381B8226A}' Version='1.0.0.0' Cache='keep' />",
79
+ }, packageElements);
80
+
81
+ var featureElements = extractResult.SelectBADataNodes("/ba:BootstrapperApplicationData/ba:WixPackageFeatureInfo")
82
+ .Cast<XmlElement>()
83
+ .Select(e => e.GetTestXml())
84
+ .ToArray();
85
+ WixAssert.CompareLineByLine(new[]
86
+ {
87
+ "<WixPackageFeatureInfo Package='MsiWithFeatures' Feature='ProductFeature' Size='34' Display='2' Level='1' Directory='' Attributes='0' />",
88
+ }, featureElements);
89
+ }
90
+ }
91
+
92
[Fact]
93
public void CanSpecifyPackagePayloadInPayloadGroup()
94
{
src/wix/test/WixToolsetTest.CoreIntegration/TestData/PackagePayload/MsiPackagePayloadInPayloadGroup.wxs
new
+18
@@ -0,0 +1,18 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3
+ <Fragment>
4
+ <PackageGroup Id="BundlePackages">
5
+ <MsiPackage Id="MsiWithFeatures" CacheId="{040011E1-F84C-4927-AD62-50A5EC19CA32}v1.0.0.0_1" EnableFeatureSelection="yes">
6
+ <PayloadGroupRef Id="PackagePayloadGroup" />
7
+ </MsiPackage>
8
+ <MsiPackage Id="MsiWithoutFeatures" CacheId="{040011E1-F84C-4927-AD62-50A5EC19CA32}v1.0.0.0_2">
9
+ <PayloadGroupRef Id="PackagePayloadGroup" />
10
+ </MsiPackage>
11
+ </PackageGroup>
12
+ </Fragment>
13
+ <Fragment>
14
+ <PayloadGroup Id="PackagePayloadGroup">
15
+ <MsiPackagePayload SourceFile="test.msi" />
16
+ </PayloadGroup>
17
+ </Fragment>
18
+</Wix>