diff options
4 files changed, 35 insertions, 31 deletions
diff --git a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs index 12a530ae..e58e2464 100644 --- a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs +++ b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs | |||
@@ -357,10 +357,7 @@ namespace WixToolset.Core.Burn | |||
357 | IEnumerable<PackageFacade> orderedFacades; | 357 | IEnumerable<PackageFacade> orderedFacades; |
358 | IEnumerable<WixBundleRollbackBoundarySymbol> boundaries; | 358 | IEnumerable<WixBundleRollbackBoundarySymbol> boundaries; |
359 | { | 359 | { |
360 | var groupSymbols = section.Symbols.OfType<WixGroupSymbol>(); | 360 | var command = new OrderPackagesAndRollbackBoundariesCommand(this.Messaging, section, facades); |
361 | var boundarySymbolsById = section.Symbols.OfType<WixBundleRollbackBoundarySymbol>().ToDictionary(b => b.Id.Id); | ||
362 | |||
363 | var command = new OrderPackagesAndRollbackBoundariesCommand(this.Messaging, groupSymbols, boundarySymbolsById, facades); | ||
364 | command.Execute(); | 361 | command.Execute(); |
365 | 362 | ||
366 | orderedFacades = command.OrderedPackageFacades; | 363 | orderedFacades = command.OrderedPackageFacades; |
diff --git a/src/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs b/src/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs index 44299fd5..f16ac707 100644 --- a/src/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs +++ b/src/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs | |||
@@ -4,27 +4,27 @@ namespace WixToolset.Core.Burn.Bundles | |||
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
7 | using System.Linq; | ||
7 | using WixToolset.Data; | 8 | using WixToolset.Data; |
8 | using WixToolset.Data.Symbols; | 9 | using WixToolset.Data.Symbols; |
9 | using WixToolset.Extensibility.Services; | 10 | using WixToolset.Extensibility.Services; |
10 | 11 | ||
11 | internal class OrderPackagesAndRollbackBoundariesCommand | 12 | internal class OrderPackagesAndRollbackBoundariesCommand |
12 | { | 13 | { |
13 | public OrderPackagesAndRollbackBoundariesCommand(IMessaging messaging, IEnumerable<WixGroupSymbol> groupSymbols, Dictionary<string, WixBundleRollbackBoundarySymbol> boundarySymbols, IDictionary<string, PackageFacade> packageFacades) | 14 | private const string DefaultBoundaryId = "WixDefaultBoundary"; |
15 | |||
16 | public OrderPackagesAndRollbackBoundariesCommand(IMessaging messaging, IntermediateSection section, IDictionary<string, PackageFacade> packageFacades) | ||
14 | { | 17 | { |
15 | this.Messaging = messaging; | 18 | this.Messaging = messaging; |
16 | this.GroupSymbols = groupSymbols; | 19 | this.Section = section; |
17 | this.Boundaries = boundarySymbols; | ||
18 | this.PackageFacades = packageFacades; | 20 | this.PackageFacades = packageFacades; |
19 | } | 21 | } |
20 | 22 | ||
21 | private IMessaging Messaging { get; } | 23 | private IMessaging Messaging { get; } |
22 | 24 | ||
23 | public IEnumerable<WixGroupSymbol> GroupSymbols { get; } | 25 | private IntermediateSection Section { get; } |
24 | |||
25 | public Dictionary<string, WixBundleRollbackBoundarySymbol> Boundaries { get; } | ||
26 | 26 | ||
27 | public IDictionary<string, PackageFacade> PackageFacades { get; } | 27 | private IDictionary<string, PackageFacade> PackageFacades { get; } |
28 | 28 | ||
29 | public IEnumerable<PackageFacade> OrderedPackageFacades { get; private set; } | 29 | public IEnumerable<PackageFacade> OrderedPackageFacades { get; private set; } |
30 | 30 | ||
@@ -32,6 +32,9 @@ namespace WixToolset.Core.Burn.Bundles | |||
32 | 32 | ||
33 | public void Execute() | 33 | public void Execute() |
34 | { | 34 | { |
35 | var groupSymbols = this.Section.Symbols.OfType<WixGroupSymbol>().ToList(); | ||
36 | var boundariesById = this.Section.Symbols.OfType<WixBundleRollbackBoundarySymbol>().ToDictionary(b => b.Id.Id); | ||
37 | |||
35 | var orderedFacades = new List<PackageFacade>(); | 38 | var orderedFacades = new List<PackageFacade>(); |
36 | var usedBoundaries = new List<WixBundleRollbackBoundarySymbol>(); | 39 | var usedBoundaries = new List<WixBundleRollbackBoundarySymbol>(); |
37 | 40 | ||
@@ -44,20 +47,27 @@ namespace WixToolset.Core.Burn.Bundles | |||
44 | // We handle uninstall (aka: backwards) rollback boundaries after | 47 | // We handle uninstall (aka: backwards) rollback boundaries after |
45 | // we get these install/repair (aka: forward) rollback boundaries | 48 | // we get these install/repair (aka: forward) rollback boundaries |
46 | // defined. | 49 | // defined. |
47 | WixBundleRollbackBoundarySymbol pendingRollbackBoundary = null; | 50 | var pendingRollbackBoundary = new WixBundleRollbackBoundarySymbol(null, new Identifier(AccessModifier.Section, DefaultBoundaryId)) { Vital = true }; |
48 | WixBundleRollbackBoundarySymbol lastRollbackBoundary = null; | 51 | var lastRollbackBoundary = pendingRollbackBoundary; |
49 | var boundaryHadX86Package = false; | 52 | var boundaryHadX86Package = false; |
50 | var warnedMsiTransaction = false; | 53 | var warnedMsiTransaction = false; |
51 | 54 | ||
52 | foreach (var groupSymbol in this.GroupSymbols) | 55 | foreach (var groupSymbol in groupSymbols) |
53 | { | 56 | { |
54 | if (ComplexReferenceChildType.Package == groupSymbol.ChildType && ComplexReferenceParentType.PackageGroup == groupSymbol.ParentType && "WixChain" == groupSymbol.ParentId) | 57 | if (ComplexReferenceChildType.Package == groupSymbol.ChildType && ComplexReferenceParentType.PackageGroup == groupSymbol.ParentType && "WixChain" == groupSymbol.ParentId) |
55 | { | 58 | { |
56 | if (this.PackageFacades.TryGetValue(groupSymbol.ChildId, out var facade)) | 59 | if (this.PackageFacades.TryGetValue(groupSymbol.ChildId, out var facade)) |
57 | { | 60 | { |
58 | var insideMsiTransaction = lastRollbackBoundary != null && lastRollbackBoundary.Transaction.HasValue && lastRollbackBoundary.Transaction.Value; | 61 | var insideMsiTransaction = lastRollbackBoundary?.Transaction ?? false; |
62 | |||
59 | if (null != pendingRollbackBoundary) | 63 | if (null != pendingRollbackBoundary) |
60 | { | 64 | { |
65 | // If we used the default boundary, ensure the symbol is added to the section. | ||
66 | if (pendingRollbackBoundary.Id.Id == DefaultBoundaryId) | ||
67 | { | ||
68 | this.Section.Symbols.Add(pendingRollbackBoundary); | ||
69 | } | ||
70 | |||
61 | if (insideMsiTransaction && !warnedMsiTransaction) | 71 | if (insideMsiTransaction && !warnedMsiTransaction) |
62 | { | 72 | { |
63 | warnedMsiTransaction = true; | 73 | warnedMsiTransaction = true; |
@@ -72,12 +82,11 @@ namespace WixToolset.Core.Burn.Bundles | |||
72 | } | 82 | } |
73 | 83 | ||
74 | // Error if MSI transaction has x86 package preceding x64 packages | 84 | // Error if MSI transaction has x86 package preceding x64 packages |
75 | if (insideMsiTransaction | 85 | if (insideMsiTransaction && boundaryHadX86Package && facade.PackageSymbol.Win64) |
76 | && boundaryHadX86Package | ||
77 | && facade.PackageSymbol.Win64) | ||
78 | { | 86 | { |
79 | this.Messaging.Write(ErrorMessages.MsiTransactionX86BeforeX64(facade.PackageSymbol.SourceLineNumbers)); | 87 | this.Messaging.Write(ErrorMessages.MsiTransactionX86BeforeX64(facade.PackageSymbol.SourceLineNumbers)); |
80 | } | 88 | } |
89 | |||
81 | boundaryHadX86Package |= !facade.PackageSymbol.Win64; | 90 | boundaryHadX86Package |= !facade.PackageSymbol.Win64; |
82 | 91 | ||
83 | orderedFacades.Add(facade); | 92 | orderedFacades.Add(facade); |
@@ -85,15 +94,16 @@ namespace WixToolset.Core.Burn.Bundles | |||
85 | else // must be a rollback boundary. | 94 | else // must be a rollback boundary. |
86 | { | 95 | { |
87 | // Discard the next rollback boundary if we have a previously defined boundary. | 96 | // Discard the next rollback boundary if we have a previously defined boundary. |
88 | var nextRollbackBoundary = this.Boundaries[groupSymbol.ChildId]; | 97 | var nextRollbackBoundary = boundariesById[groupSymbol.ChildId]; |
89 | if (null != pendingRollbackBoundary) | 98 | if (null != pendingRollbackBoundary) |
90 | { | 99 | { |
91 | this.Messaging.Write(WarningMessages.DiscardedRollbackBoundary(nextRollbackBoundary.SourceLineNumbers, nextRollbackBoundary.Id.Id)); | 100 | if (pendingRollbackBoundary.Id.Id != DefaultBoundaryId) |
92 | } | 101 | { |
93 | else | 102 | this.Messaging.Write(WarningMessages.DiscardedRollbackBoundary(nextRollbackBoundary.SourceLineNumbers, nextRollbackBoundary.Id.Id)); |
94 | { | 103 | } |
95 | lastRollbackBoundary = pendingRollbackBoundary = nextRollbackBoundary; | ||
96 | } | 104 | } |
105 | |||
106 | lastRollbackBoundary = pendingRollbackBoundary = nextRollbackBoundary; | ||
97 | } | 107 | } |
98 | } | 108 | } |
99 | } | 109 | } |
@@ -135,7 +145,7 @@ namespace WixToolset.Core.Burn.Bundles | |||
135 | string previousRollbackBoundaryId = null; | 145 | string previousRollbackBoundaryId = null; |
136 | PackageFacade previousFacade = null; | 146 | PackageFacade previousFacade = null; |
137 | 147 | ||
138 | foreach (PackageFacade package in orderedFacades) | 148 | foreach (var package in orderedFacades) |
139 | { | 149 | { |
140 | if (null != package.PackageSymbol.RollbackBoundaryRef) | 150 | if (null != package.PackageSymbol.RollbackBoundaryRef) |
141 | { | 151 | { |
diff --git a/src/WixToolset.Core/Compiler_Bundle.cs b/src/WixToolset.Core/Compiler_Bundle.cs index 89ca94ba..cc4550a8 100644 --- a/src/WixToolset.Core/Compiler_Bundle.cs +++ b/src/WixToolset.Core/Compiler_Bundle.cs | |||
@@ -1726,11 +1726,8 @@ namespace WixToolset.Core | |||
1726 | } | 1726 | } |
1727 | } | 1727 | } |
1728 | 1728 | ||
1729 | // Ensure there is always a rollback boundary at the beginning of the chain. | 1729 | string previousId = null; |
1730 | this.CreateRollbackBoundary(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixDefaultBoundary"), YesNoType.Yes, YesNoType.No, ComplexReferenceParentType.PackageGroup, "WixChain", ComplexReferenceChildType.Unknown, null); | 1730 | var previousType = ComplexReferenceChildType.Unknown; |
1731 | |||
1732 | var previousId = "WixDefaultBoundary"; | ||
1733 | var previousType = ComplexReferenceChildType.Package; | ||
1734 | 1731 | ||
1735 | foreach (var child in node.Elements()) | 1732 | foreach (var child in node.Elements()) |
1736 | { | 1733 | { |
diff --git a/src/test/WixToolsetTest.CoreIntegration/RollbackBoundaryFixture.cs b/src/test/WixToolsetTest.CoreIntegration/RollbackBoundaryFixture.cs index b713920c..9e19abb0 100644 --- a/src/test/WixToolsetTest.CoreIntegration/RollbackBoundaryFixture.cs +++ b/src/test/WixToolsetTest.CoreIntegration/RollbackBoundaryFixture.cs | |||
@@ -9,7 +9,7 @@ namespace WixToolsetTest.CoreIntegration | |||
9 | 9 | ||
10 | public class RollbackBoundaryFixture | 10 | public class RollbackBoundaryFixture |
11 | { | 11 | { |
12 | [Fact(Skip = "Test demonstrates failure")] | 12 | [Fact] |
13 | public void CanStartChainWithRollbackBoundary() | 13 | public void CanStartChainWithRollbackBoundary() |
14 | { | 14 | { |
15 | var folder = TestData.Get(@"TestData"); | 15 | var folder = TestData.Get(@"TestData"); |