aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-04-13 12:16:37 -0500
committerSean Hall <r.sean.hall@gmail.com>2022-04-13 13:13:48 -0500
commitfaa9777b7720a935b28c33c3fa1088cd7bcc2f86 (patch)
tree1563c0ddb70a695188ecc9cbfd66d73865a49a7f
parent4c3640ad5ef05b5be44df2aee2a23baa40471422 (diff)
downloadwix-faa9777b7720a935b28c33c3fa1088cd7bcc2f86.tar.gz
wix-faa9777b7720a935b28c33c3fa1088cd7bcc2f86.tar.bz2
wix-faa9777b7720a935b28c33c3fa1088cd7bcc2f86.zip
Add support for remote BundlePackagePayload.
-rw-r--r--src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs3
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs2
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs2
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs2
-rw-r--r--src/wix/WixToolset.Core/CompilerCore.cs5
-rw-r--r--src/wix/WixToolset.Core/Compiler_Bundle.cs284
-rw-r--r--src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs4
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/BundlePackageFixture.cs87
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundlePackage/RemoteBundlePackage.wxs28
9 files changed, 407 insertions, 10 deletions
diff --git a/src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs b/src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs
index 3a71d120..546a43a7 100644
--- a/src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs
+++ b/src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs
@@ -422,7 +422,8 @@ namespace WixToolset.Extensibility.Services
422 /// <param name="intermediate">Parent intermediate.</param> 422 /// <param name="intermediate">Parent intermediate.</param>
423 /// <param name="section">Parent section.</param> 423 /// <param name="section">Parent section.</param>
424 /// <param name="element">Element to parse children.</param> 424 /// <param name="element">Element to parse children.</param>
425 void ParseForExtensionElements(IEnumerable<ICompilerExtension> extensions, Intermediate intermediate, IntermediateSection section, XElement element); 425 /// <param name="context">Extra information about the context in which this element is being parsed.</param>
426 void ParseForExtensionElements(IEnumerable<ICompilerExtension> extensions, Intermediate intermediate, IntermediateSection section, XElement element, IDictionary<string, string> context = null);
426 427
427 /// <summary> 428 /// <summary>
428 /// Schedules an action symbol. 429 /// Schedules an action symbol.
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs
index c5a1aee0..c8e6bcf2 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs
@@ -57,7 +57,7 @@ namespace WixToolset.Core.Burn.Bundles
57 public void Execute() 57 public void Execute()
58 { 58 {
59 var harvestedBundlePackage = this.Section.Symbols.OfType<WixBundleHarvestedBundlePackageSymbol>() 59 var harvestedBundlePackage = this.Section.Symbols.OfType<WixBundleHarvestedBundlePackageSymbol>()
60 .Where(h => h.Id == this.PackagePayload.Id) 60 .Where(h => h.Id.Id == this.PackagePayload.Id.Id)
61 .SingleOrDefault(); 61 .SingleOrDefault();
62 62
63 if (harvestedBundlePackage == null) 63 if (harvestedBundlePackage == null)
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
index 0bec201d..d640e85d 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
@@ -65,7 +65,7 @@ namespace WixToolset.Core.Burn.Bundles
65 public void Execute() 65 public void Execute()
66 { 66 {
67 var harvestedMsiPackage = this.Section.Symbols.OfType<WixBundleHarvestedMsiPackageSymbol>() 67 var harvestedMsiPackage = this.Section.Symbols.OfType<WixBundleHarvestedMsiPackageSymbol>()
68 .Where(h => h.Id == this.PackagePayload.Id) 68 .Where(h => h.Id.Id == this.PackagePayload.Id.Id)
69 .SingleOrDefault(); 69 .SingleOrDefault();
70 70
71 if (harvestedMsiPackage == null) 71 if (harvestedMsiPackage == null)
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs
index 466ef5b9..5b43e614 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs
@@ -53,7 +53,7 @@ namespace WixToolset.Core.Burn.Bundles
53 public void Execute() 53 public void Execute()
54 { 54 {
55 var harvestedMspPackage = this.Section.Symbols.OfType<WixBundleHarvestedMspPackageSymbol>() 55 var harvestedMspPackage = this.Section.Symbols.OfType<WixBundleHarvestedMspPackageSymbol>()
56 .Where(h => h.Id == this.PackagePayload.Id) 56 .Where(h => h.Id.Id == this.PackagePayload.Id.Id)
57 .SingleOrDefault(); 57 .SingleOrDefault();
58 58
59 if (harvestedMspPackage == null) 59 if (harvestedMspPackage == null)
diff --git a/src/wix/WixToolset.Core/CompilerCore.cs b/src/wix/WixToolset.Core/CompilerCore.cs
index e23b1e70..0fd302e5 100644
--- a/src/wix/WixToolset.Core/CompilerCore.cs
+++ b/src/wix/WixToolset.Core/CompilerCore.cs
@@ -849,9 +849,10 @@ namespace WixToolset.Core
849 /// Process all children of the element looking for extensions and erroring on the unexpected. 849 /// Process all children of the element looking for extensions and erroring on the unexpected.
850 /// </summary> 850 /// </summary>
851 /// <param name="element">Element to parse children.</param> 851 /// <param name="element">Element to parse children.</param>
852 public void ParseForExtensionElements(XElement element) 852 /// <param name="context">Extra information about the context in which this element is being parsed.</param>
853 public void ParseForExtensionElements(XElement element, IDictionary<string, string> context = null)
853 { 854 {
854 this.parseHelper.ParseForExtensionElements(this.extensions.Values, this.intermediate, this.ActiveSection, element); 855 this.parseHelper.ParseForExtensionElements(this.extensions.Values, this.intermediate, this.ActiveSection, element, context);
855 } 856 }
856 857
857 /// <summary> 858 /// <summary>
diff --git a/src/wix/WixToolset.Core/Compiler_Bundle.cs b/src/wix/WixToolset.Core/Compiler_Bundle.cs
index ab405684..4cbfe58a 100644
--- a/src/wix/WixToolset.Core/Compiler_Bundle.cs
+++ b/src/wix/WixToolset.Core/Compiler_Bundle.cs
@@ -2552,7 +2552,7 @@ namespace WixToolset.Core
2552 var compilerPayload = new CompilerPayload(this.Core, sourceLineNumbers, node) 2552 var compilerPayload = new CompilerPayload(this.Core, sourceLineNumbers, node)
2553 { 2553 {
2554 Id = defaultId, 2554 Id = defaultId,
2555 IsRemoteAllowed = packageType == WixBundlePackageType.Exe || packageType == WixBundlePackageType.Msu, 2555 IsRemoteAllowed = packageType == WixBundlePackageType.Bundle || packageType == WixBundlePackageType.Exe || packageType == WixBundlePackageType.Msu,
2556 }; 2556 };
2557 2557
2558 // This list lets us evaluate extension attributes *after* all core attributes 2558 // This list lets us evaluate extension attributes *after* all core attributes
@@ -2659,11 +2659,291 @@ namespace WixToolset.Core
2659 this.Core.ParseExtensionAttribute(node, extensionAttribute, context); 2659 this.Core.ParseExtensionAttribute(node, extensionAttribute, context);
2660 } 2660 }
2661 2661
2662 this.Core.ParseForExtensionElements(node); 2662 foreach (var child in node.Elements())
2663 {
2664 if (CompilerCore.WixNamespace == child.Name.Namespace)
2665 {
2666 bool allowed;
2667 switch (child.Name.LocalName)
2668 {
2669 case "RemoteBundle":
2670 allowed = packageType == WixBundlePackageType.Bundle;
2671
2672 if (allowed)
2673 {
2674 this.ParseRemoteBundleElement(child, compilerPayload.Id.Id);
2675 }
2676
2677 break;
2678 default:
2679 allowed = false;
2680 break;
2681 }
2682
2683 if (!allowed)
2684 {
2685 this.Core.UnexpectedElement(node, child);
2686 }
2687 }
2688 else
2689 {
2690 this.Core.ParseExtensionElement(node, child, context);
2691 }
2692 }
2663 2693
2664 return compilerPayload; 2694 return compilerPayload;
2665 } 2695 }
2666 2696
2697 private void ParseRemoteBundleElement(XElement node, string packagePayloadId)
2698 {
2699 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2700 string bundleId = null;
2701 string displayName = null;
2702 string engineVersion = null;
2703 long? installSize = null;
2704 string manifestNamespace = null;
2705 var perMachine = YesNoType.NotSet;
2706 var protocolVersion = -1;
2707 string providerKey = null;
2708 string upgradeCode = null;
2709 string version = null;
2710 var win64 = YesNoType.NotSet;
2711
2712 foreach (var attrib in node.Attributes())
2713 {
2714 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
2715 {
2716 switch (attrib.Name.LocalName)
2717 {
2718 case "BundleId":
2719 bundleId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib);
2720 break;
2721 case "DisplayName":
2722 displayName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2723 break;
2724 case "EngineVersion":
2725 engineVersion = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
2726 break;
2727 case "InstallSize":
2728 installSize = this.Core.GetAttributeLongValue(sourceLineNumbers, attrib, 0, Int64.MaxValue);
2729 break;
2730 case "ManifestNamespace":
2731 manifestNamespace = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2732 break;
2733 case "PerMachine":
2734 perMachine = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2735 break;
2736 case "ProtocolVersion":
2737 protocolVersion = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, Int32.MaxValue);
2738 break;
2739 case "ProviderKey":
2740 providerKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2741 break;
2742 case "UpgradeCode":
2743 upgradeCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib);
2744 break;
2745 case "Version":
2746 version = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
2747 break;
2748 case "Win64":
2749 win64 = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2750 break;
2751 default:
2752 this.Core.UnexpectedAttribute(node, attrib);
2753 break;
2754 }
2755 }
2756 else
2757 {
2758 this.Core.ParseExtensionAttribute(node, attrib);
2759 }
2760 }
2761
2762 if (String.IsNullOrEmpty(bundleId))
2763 {
2764 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "BundleId"));
2765 }
2766
2767 if (String.IsNullOrEmpty(manifestNamespace))
2768 {
2769 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ManifestNamespace"));
2770 }
2771
2772 if (perMachine == YesNoType.NotSet)
2773 {
2774 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PerMachine"));
2775 }
2776
2777 if (protocolVersion == -1)
2778 {
2779 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ProtocolVersion"));
2780 }
2781
2782 if (String.IsNullOrEmpty(providerKey))
2783 {
2784 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ProviderKey"));
2785 }
2786
2787 if (String.IsNullOrEmpty(upgradeCode))
2788 {
2789 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "UpgradeCode"));
2790 }
2791
2792 if (String.IsNullOrEmpty(version))
2793 {
2794 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
2795 }
2796
2797 if (win64 == YesNoType.NotSet)
2798 {
2799 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Win64"));
2800 }
2801
2802 if (!this.Messaging.EncounteredError)
2803 {
2804 WixBundleHarvestedBundlePackageAttributes bundleAttributes = 0;
2805 bundleAttributes |= (YesNoType.Yes == perMachine) ? WixBundleHarvestedBundlePackageAttributes.PerMachine : 0;
2806 bundleAttributes |= (YesNoType.Yes == win64) ? WixBundleHarvestedBundlePackageAttributes.Win64 : 0;
2807
2808 var symbol = this.Core.AddSymbol(new WixBundleHarvestedBundlePackageSymbol(sourceLineNumbers, new Identifier(AccessModifier.Section, packagePayloadId))
2809 {
2810 Attributes = bundleAttributes,
2811 BundleId = bundleId,
2812 DisplayName = displayName,
2813 EngineVersion = engineVersion,
2814 ManifestNamespace = manifestNamespace,
2815 ProtocolVersion = protocolVersion,
2816 Version = version,
2817 });
2818
2819 if (installSize.HasValue)
2820 {
2821 symbol.InstallSize = installSize.Value;
2822 }
2823
2824 this.Core.AddSymbol(new WixBundlePackageRelatedBundleSymbol(sourceLineNumbers)
2825 {
2826 PackagePayloadRef = packagePayloadId,
2827 BundleId = upgradeCode,
2828 Action = RelatedBundleActionType.Upgrade,
2829 });
2830
2831 var depId = new Identifier(AccessModifier.Section, this.Core.CreateIdentifier("dep", packagePayloadId, providerKey));
2832 this.Core.AddSymbol(new WixBundleHarvestedDependencyProviderSymbol(sourceLineNumbers, depId)
2833 {
2834 PackagePayloadRef = packagePayloadId,
2835 ProviderKey = providerKey,
2836 Version = version,
2837 });
2838 }
2839
2840 var context = new Dictionary<string, string>
2841 {
2842 ["Id"] = packagePayloadId,
2843 };
2844
2845 foreach (var child in node.Elements())
2846 {
2847 if (CompilerCore.WixNamespace == child.Name.Namespace)
2848 {
2849 switch (child.Name.LocalName)
2850 {
2851 case "RemoteRelatedBundle":
2852 this.ParseRemoteRelatedBundleElement(child, packagePayloadId);
2853 break;
2854 default:
2855 this.Core.UnexpectedElement(node, child);
2856 break;
2857 }
2858 }
2859 else
2860 {
2861 this.Core.ParseExtensionElement(node, child, context);
2862 }
2863 }
2864 }
2865
2866 private void ParseRemoteRelatedBundleElement(XElement node, string payloadId)
2867 {
2868 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2869 string id = null;
2870 RelatedBundleActionType? actionType = null;
2871
2872 foreach (var attrib in node.Attributes())
2873 {
2874 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
2875 {
2876 switch (attrib.Name.LocalName)
2877 {
2878 case "Id":
2879 id = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
2880 break;
2881 case "Action":
2882 var action = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2883 switch (action)
2884 {
2885 case "Detect":
2886 case "detect":
2887 actionType = RelatedBundleActionType.Detect;
2888 break;
2889 case "Upgrade":
2890 case "upgrade":
2891 actionType = RelatedBundleActionType.Upgrade;
2892 break;
2893 case "Addon":
2894 case "addon":
2895 actionType = RelatedBundleActionType.Addon;
2896 break;
2897 case "Patch":
2898 case "patch":
2899 actionType = RelatedBundleActionType.Patch;
2900 break;
2901 case "":
2902 break;
2903 default:
2904 this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Action", action, "Detect", "Upgrade", "Addon", "Patch"));
2905 break;
2906 }
2907 break;
2908 default:
2909 this.Core.UnexpectedAttribute(node, attrib);
2910 break;
2911 }
2912 }
2913 else
2914 {
2915 this.Core.ParseExtensionAttribute(node, attrib);
2916 }
2917 }
2918
2919 if (null == id)
2920 {
2921 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
2922 }
2923
2924 if (!actionType.HasValue)
2925 {
2926 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Action"));
2927 }
2928
2929 var context = new Dictionary<string, string>
2930 {
2931 ["PayloadId"] = payloadId,
2932 };
2933
2934 this.Core.ParseForExtensionElements(node, context);
2935
2936 if (!this.Core.EncounteredError)
2937 {
2938 this.Core.AddSymbol(new WixBundlePackageRelatedBundleSymbol(sourceLineNumbers)
2939 {
2940 PackagePayloadRef = payloadId,
2941 BundleId = id,
2942 Action = actionType.Value,
2943 });
2944 }
2945 }
2946
2667 /// <summary> 2947 /// <summary>
2668 /// Parse CommandLine element. 2948 /// Parse CommandLine element.
2669 /// </summary> 2949 /// </summary>
diff --git a/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs b/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
index 654b56dc..bab1dd34 100644
--- a/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
+++ b/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
@@ -714,7 +714,7 @@ namespace WixToolset.Core.ExtensibilityServices
714 return keyPath; 714 return keyPath;
715 } 715 }
716 716
717 public void ParseForExtensionElements(IEnumerable<ICompilerExtension> extensions, Intermediate intermediate, IntermediateSection section, XElement element) 717 public void ParseForExtensionElements(IEnumerable<ICompilerExtension> extensions, Intermediate intermediate, IntermediateSection section, XElement element, IDictionary<string, string> context = null)
718 { 718 {
719 var checkInnerText = false; 719 var checkInnerText = false;
720 720
@@ -728,7 +728,7 @@ namespace WixToolset.Core.ExtensibilityServices
728 } 728 }
729 else 729 else
730 { 730 {
731 this.ParseExtensionElement(extensions, intermediate, section, element, childElement); 731 this.ParseExtensionElement(extensions, intermediate, section, element, childElement, context);
732 } 732 }
733 } 733 }
734 else 734 else
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/BundlePackageFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/BundlePackageFixture.cs
index 2925abb1..621d0871 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/BundlePackageFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/BundlePackageFixture.cs
@@ -205,6 +205,93 @@ namespace WixToolsetTest.CoreIntegration
205 } 205 }
206 206
207 [Fact] 207 [Fact]
208 public void CanBuildBundleWithRemoteBundlePackage()
209 {
210 var folder = TestData.Get(@"TestData");
211
212 using (var fs = new DisposableFileSystem())
213 {
214 var baseFolder = fs.GetFolder();
215 var parentIntermediateFolder = Path.Combine(baseFolder, "obj", "Parent");
216 var binFolder = Path.Combine(baseFolder, "bin");
217 var parentBundlePath = Path.Combine(binFolder, "parent.exe");
218 var parentPdbPath = Path.Combine(binFolder, "parent.wixpdb");
219 var parentBaFolderPath = Path.Combine(baseFolder, "parentba");
220 var extractFolderPath = Path.Combine(baseFolder, "extract");
221
222 var result = WixRunner.Execute(new[]
223 {
224 "build",
225 Path.Combine(folder, "BundlePackage", "RemoteBundlePackage.wxs"),
226 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
227 "-bindpath", binFolder,
228 "-intermediateFolder", parentIntermediateFolder,
229 "-o", parentBundlePath,
230 });
231
232 result.AssertSuccess();
233
234 Assert.True(File.Exists(parentBundlePath));
235
236 var chainBundleId = "{216BDA7F-74BD-45E8-957B-500552F05629}";
237 string parentBundleId;
238 using (var wixOutput = WixOutput.Read(parentPdbPath))
239 {
240
241 var intermediate = Intermediate.Load(wixOutput);
242 var section = intermediate.Sections.Single();
243
244 var bundleSymbol = section.Symbols.OfType<WixBundleSymbol>().Single();
245 parentBundleId = bundleSymbol.BundleId;
246 }
247
248 var extractResult = BundleExtractor.ExtractBAContainer(null, parentBundlePath, parentBaFolderPath, extractFolderPath);
249 extractResult.AssertSuccess();
250
251 var ignoreAttributesByElementName = new Dictionary<string, List<string>>
252 {
253 { "BundlePackage", new List<string> { "Size" } },
254 };
255 var bundlePackages = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Chain/burn:BundlePackage")
256 .Cast<XmlElement>()
257 .Select(e => e.GetTestXml(ignoreAttributesByElementName))
258 .ToArray();
259 WixAssert.CompareLineByLine(new string[]
260 {
261 $"<BundlePackage Id='chain.exe' Cache='keep' CacheId='{chainBundleId}v1.0.0.0' InstallSize='34' Size='*' PerMachine='yes' Permanent='yes' Vital='yes' RollbackBoundaryForward='WixDefaultBoundary' RollbackBoundaryBackward='WixDefaultBoundary' LogPathVariable='WixBundleLog_chain.exe' RollbackLogPathVariable='WixBundleRollbackLog_chain.exe' BundleId='{chainBundleId}' Version='1.0.0.0' InstallArguments='' UninstallArguments='' RepairArguments='' SupportsBurnProtocol='yes' Win64='no'>" +
262 "<Provides Key='MyProviderKey,v1.0' Version='1.0.0.0' DisplayName='BurnBundle' Imported='yes' />" +
263 "<RelatedBundle Id='{B94478B1-E1F3-4700-9CE8-6AA090854AEC}' Action='Upgrade' />" +
264 "<PayloadRef Id='chain.exe' />" +
265 "</BundlePackage>",
266 }, bundlePackages);
267
268 var registrations = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Registration")
269 .Cast<XmlElement>()
270 .Select(e => e.GetTestXml())
271 .ToArray();
272 WixAssert.CompareLineByLine(new string[]
273 {
274 $"<Registration Id='{parentBundleId}' ExecutableName='parent.exe' PerMachine='yes' Tag='' Version='1.0.1.0' ProviderKey='{parentBundleId}'>" +
275 "<Arp DisplayName='RemoteBundlePackageBundle' DisplayVersion='1.0.1.0' Publisher='Example Corporation' />" +
276 "</Registration>"
277 }, registrations);
278
279 ignoreAttributesByElementName = new Dictionary<string, List<string>>
280 {
281 { "WixPackageProperties", new List<string> { "DownloadSize", "PackageSize" } },
282 };
283 var packageElements = extractResult.SelectBADataNodes("/ba:BootstrapperApplicationData/ba:WixPackageProperties")
284 .Cast<XmlElement>()
285 .Select(e => e.GetTestXml(ignoreAttributesByElementName))
286 .ToArray();
287 WixAssert.CompareLineByLine(new string[]
288 {
289 "<WixPackageProperties Package='chain.exe' Vital='yes' DisplayName='BurnBundle' Description='BurnBundleDescription' DownloadSize='*' PackageSize='*' InstalledSize='34' PackageType='Bundle' Permanent='yes' LogPathVariable='WixBundleLog_chain.exe' RollbackLogPathVariable='WixBundleRollbackLog_chain.exe' Compressed='no' Version='1.0.0.0' Cache='keep' />",
290 }, packageElements);
291 }
292 }
293
294 [Fact]
208 public void CanBuildBundleWithV3BundlePackage() 295 public void CanBuildBundleWithV3BundlePackage()
209 { 296 {
210 var folder = TestData.Get(@"TestData"); 297 var folder = TestData.Get(@"TestData");
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundlePackage/RemoteBundlePackage.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundlePackage/RemoteBundlePackage.wxs
new file mode 100644
index 00000000..1a2b17f5
--- /dev/null
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundlePackage/RemoteBundlePackage.wxs
@@ -0,0 +1,28 @@
1<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2 <Bundle Name="RemoteBundlePackageBundle" Version="1.0.1.0" Manufacturer="Example Corporation" UpgradeCode="{9BE68A41-FD0E-4E25-B607-D636E42AFEF6}">
3 <BootstrapperApplication>
4 <BootstrapperApplicationDll SourceFile="fakeba.dll" />
5 </BootstrapperApplication>
6 <Chain>
7 <BundlePackage Permanent="yes">
8 <BundlePackagePayload Name="chain.exe"
9 DownloadUrl="http://example.com/chain.exe"
10 Description="BurnBundleDescription"
11 Size="123456789"
12 Hash="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA">
13 <RemoteBundle BundleId="{216BDA7F-74BD-45E8-957B-500552F05629}"
14 DisplayName="BurnBundle"
15 InstallSize="34"
16 ManifestNamespace="http://wixtoolset.org/schemas/v4/2008/Burn"
17 PerMachine="yes"
18 ProtocolVersion="1"
19 ProviderKey="MyProviderKey,v1.0"
20 UpgradeCode="{B94478B1-E1F3-4700-9CE8-6AA090854AEC}"
21 Version="1.0.0.0"
22 Win64="no"
23 />
24 </BundlePackagePayload>
25 </BundlePackage>
26 </Chain>
27 </Bundle>
28</Wix>