diff options
author | Rob Mensching <rob@firegiant.com> | 2024-07-12 23:23:43 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2024-07-15 15:21:20 -0700 |
commit | 0fb9a659a9045279e88fd418fa0342ca2ef7027e (patch) | |
tree | 310dfd52614641ad387660df1270d446ec9e1a32 | |
parent | e081c743d4d6e73bb6997aef9cd724dd255d5ba4 (diff) | |
download | wix-0fb9a659a9045279e88fd418fa0342ca2ef7027e.tar.gz wix-0fb9a659a9045279e88fd418fa0342ca2ef7027e.tar.bz2 wix-0fb9a659a9045279e88fd418fa0342ca2ef7027e.zip |
Scheduling standard actions must override virtual definitions from stdlib
Fixes 8115
5 files changed, 162 insertions, 4 deletions
diff --git a/src/wix/WixToolset.Core/Compiler_Package.cs b/src/wix/WixToolset.Core/Compiler_Package.cs index 4b934fa9..74b3aae2 100644 --- a/src/wix/WixToolset.Core/Compiler_Package.cs +++ b/src/wix/WixToolset.Core/Compiler_Package.cs | |||
@@ -2504,8 +2504,8 @@ namespace WixToolset.Core | |||
2504 | var exitSequence = CompilerConstants.IntegerNotSet; | 2504 | var exitSequence = CompilerConstants.IntegerNotSet; |
2505 | var sequence = CompilerConstants.IntegerNotSet; | 2505 | var sequence = CompilerConstants.IntegerNotSet; |
2506 | var showDialog = "Show" == actionName; | 2506 | var showDialog = "Show" == actionName; |
2507 | var specialAction = "InstallExecute" == actionName || "InstallExecuteAgain" == actionName || "RemoveExistingProducts" == actionName || "DisableRollback" == actionName || "ScheduleReboot" == actionName || "ForceReboot" == actionName || "ResolveSource" == actionName; | 2507 | var specialAction = "InstallExecute" == actionName || "InstallExecuteAgain" == actionName || "RemoveExistingProducts" == actionName || "DisableRollback" == actionName || "ScheduleReboot" == actionName || "ForceReboot" == actionName || "ResolveSource" == actionName; // these actions do NOT have default sequence numbers and MUST be scheduled. |
2508 | var specialStandardAction = "AppSearch" == actionName || "CCPSearch" == actionName || "RMCCPSearch" == actionName || "LaunchConditions" == actionName || "FindRelatedProducts" == actionName; | 2508 | var specialStandardAction = "AppSearch" == actionName || "CCPSearch" == actionName || "RMCCPSearch" == actionName || "LaunchConditions" == actionName || "FindRelatedProducts" == actionName; // these standard actions have default sequence numbers so they do NOT have to be scheduled. |
2509 | var suppress = false; | 2509 | var suppress = false; |
2510 | 2510 | ||
2511 | foreach (var attrib in child.Attributes()) | 2511 | foreach (var attrib in child.Attributes()) |
@@ -2608,6 +2608,8 @@ namespace WixToolset.Core | |||
2608 | } | 2608 | } |
2609 | } | 2609 | } |
2610 | 2610 | ||
2611 | var standardAction = WindowsInstallerStandard.IsStandardAction(actionName); | ||
2612 | |||
2611 | if (customAction && "Custom" == actionName) | 2613 | if (customAction && "Custom" == actionName) |
2612 | { | 2614 | { |
2613 | this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Action")); | 2615 | this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Action")); |
@@ -2653,7 +2655,7 @@ namespace WixToolset.Core | |||
2653 | } | 2655 | } |
2654 | 2656 | ||
2655 | // normal standard actions cannot be set overridable by the user (since they are overridable by default) | 2657 | // normal standard actions cannot be set overridable by the user (since they are overridable by default) |
2656 | if (overridable && WindowsInstallerStandard.IsStandardAction(actionName) && !specialAction) | 2658 | if (overridable && standardAction && !specialAction) |
2657 | { | 2659 | { |
2658 | this.Core.Write(ErrorMessages.UnexpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Overridable")); | 2660 | this.Core.Write(ErrorMessages.UnexpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Overridable")); |
2659 | } | 2661 | } |
@@ -2688,6 +2690,10 @@ namespace WixToolset.Core | |||
2688 | { | 2690 | { |
2689 | access = actionIdentifier.Access; | 2691 | access = actionIdentifier.Access; |
2690 | } | 2692 | } |
2693 | else if (standardAction) | ||
2694 | { | ||
2695 | access = AccessModifier.Override; | ||
2696 | } | ||
2691 | 2697 | ||
2692 | var symbol = this.Core.AddSymbol(new WixActionSymbol(childSourceLineNumbers, new Identifier(access, sequenceTable, actionName)) | 2698 | var symbol = this.Core.AddSymbol(new WixActionSymbol(childSourceLineNumbers, new Identifier(access, sequenceTable, actionName)) |
2693 | { | 2699 | { |
diff --git a/src/wix/WixToolset.Core/Link/ProcessConflictingSymbolsCommand.cs b/src/wix/WixToolset.Core/Link/ProcessConflictingSymbolsCommand.cs index 556a24d7..805dbce4 100644 --- a/src/wix/WixToolset.Core/Link/ProcessConflictingSymbolsCommand.cs +++ b/src/wix/WixToolset.Core/Link/ProcessConflictingSymbolsCommand.cs | |||
@@ -131,9 +131,16 @@ namespace WixToolset.Core.Link | |||
131 | // Ensure referenced override symbols actually overrode a virtual symbol. | 131 | // Ensure referenced override symbols actually overrode a virtual symbol. |
132 | foreach (var referencedOverrideSymbol in this.OverrideSymbols.Where(s => this.ResolvedSections.Contains(s.Section))) | 132 | foreach (var referencedOverrideSymbol in this.OverrideSymbols.Where(s => this.ResolvedSections.Contains(s.Section))) |
133 | { | 133 | { |
134 | // The easiest check is to see if the symbol overrode a virtual symbol. If not, check to see if there were any possible | ||
135 | // virtual symbols that could have been overridden. If not, then we have an error. | ||
134 | if (referencedOverrideSymbol.Overrides is null) | 136 | if (referencedOverrideSymbol.Overrides is null) |
135 | { | 137 | { |
136 | this.Messaging.Write(LinkerErrors.VirtualSymbolNotFoundForOverride(referencedOverrideSymbol.Symbol)); | 138 | var otherVirtualsCount = referencedOverrideSymbol.PossiblyConflicts.Count(s => s.Access == AccessModifier.Virtual); |
139 | |||
140 | if (otherVirtualsCount == 0) | ||
141 | { | ||
142 | this.Messaging.Write(LinkerErrors.VirtualSymbolNotFoundForOverride(referencedOverrideSymbol.Symbol)); | ||
143 | } | ||
137 | } | 144 | } |
138 | } | 145 | } |
139 | 146 | ||
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/StandardActionFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/StandardActionFixture.cs new file mode 100644 index 00000000..23cf30ae --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/StandardActionFixture.cs | |||
@@ -0,0 +1,124 @@ | |||
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 WixToolsetTest.CoreIntegration | ||
4 | { | ||
5 | using System.IO; | ||
6 | using System.Linq; | ||
7 | using WixInternal.Core.TestPackage; | ||
8 | using WixInternal.TestSupport; | ||
9 | using Xunit; | ||
10 | |||
11 | public class StandardActionFixture | ||
12 | { | ||
13 | [Fact] | ||
14 | public void CanCompileSpecialActionWithOverride() | ||
15 | { | ||
16 | using var fs = new DisposableFileSystem(); | ||
17 | |||
18 | var results = BuildAndQueryMsi(fs, "SpecialActionOverride.wxs"); | ||
19 | |||
20 | WixAssert.CompareLineByLine(new[] | ||
21 | { | ||
22 | "InstallExecuteSequence:AppSearch\t\t99", | ||
23 | "InstallExecuteSequence:CostFinalize\t\t1000", | ||
24 | "InstallExecuteSequence:CostInitialize\t\t800", | ||
25 | "InstallExecuteSequence:CreateFolders\t\t3700", | ||
26 | "InstallExecuteSequence:FileCost\t\t900", | ||
27 | "InstallExecuteSequence:FindRelatedProducts\t\t98", | ||
28 | "InstallExecuteSequence:InstallFiles\t\t4000", | ||
29 | "InstallExecuteSequence:InstallFinalize\t\t6600", | ||
30 | "InstallExecuteSequence:InstallInitialize\t\t1500", | ||
31 | "InstallExecuteSequence:InstallValidate\t\t1400", | ||
32 | "InstallExecuteSequence:LaunchConditions\t\t100", | ||
33 | "InstallExecuteSequence:MigrateFeatureStates\t\t1200", | ||
34 | "InstallExecuteSequence:ProcessComponents\t\t1600", | ||
35 | "InstallExecuteSequence:PublishFeatures\t\t6300", | ||
36 | "InstallExecuteSequence:PublishProduct\t\t6400", | ||
37 | "InstallExecuteSequence:RegisterProduct\t\t6100", | ||
38 | "InstallExecuteSequence:RegisterUser\t\t6000", | ||
39 | "InstallExecuteSequence:RemoveExistingProducts\t\t1401", | ||
40 | "InstallExecuteSequence:RemoveFiles\t\t3500", | ||
41 | "InstallExecuteSequence:RemoveFolders\t\t3600", | ||
42 | "InstallExecuteSequence:UnpublishFeatures\t\t1800", | ||
43 | "InstallExecuteSequence:ValidateProductID\t\t700", | ||
44 | "InstallUISequence:CostFinalize\t\t1000", | ||
45 | "InstallUISequence:CostInitialize\t\t800", | ||
46 | "InstallUISequence:ExecuteAction\t\t1300", | ||
47 | "InstallUISequence:FileCost\t\t900", | ||
48 | "InstallUISequence:FindRelatedProducts\t\t25", | ||
49 | "InstallUISequence:LaunchConditions\t\t100", | ||
50 | "InstallUISequence:MigrateFeatureStates\t\t1200", | ||
51 | "InstallUISequence:ValidateProductID\t\t700", | ||
52 | }, results); | ||
53 | } | ||
54 | |||
55 | [Fact] | ||
56 | public void CanCompileStandardActionWithOverride() | ||
57 | { | ||
58 | using var fs = new DisposableFileSystem(); | ||
59 | |||
60 | var results = BuildAndQueryMsi(fs, "StandardActionOverride.wxs"); | ||
61 | |||
62 | WixAssert.CompareLineByLine(new[] | ||
63 | { | ||
64 | "InstallExecuteSequence:CostFinalize\t\t1000", | ||
65 | "InstallExecuteSequence:CostInitialize\t\t800", | ||
66 | "InstallExecuteSequence:CreateFolders\t\t3700", | ||
67 | "InstallExecuteSequence:FileCost\t\t900", | ||
68 | "InstallExecuteSequence:FindRelatedProducts\t\t25", | ||
69 | "InstallExecuteSequence:InstallFiles\tTEST_CONDITION\t4000", | ||
70 | "InstallExecuteSequence:InstallFinalize\t\t6600", | ||
71 | "InstallExecuteSequence:InstallInitialize\t\t1500", | ||
72 | "InstallExecuteSequence:InstallValidate\t\t1400", | ||
73 | "InstallExecuteSequence:LaunchConditions\t\t100", | ||
74 | "InstallExecuteSequence:MigrateFeatureStates\t\t1200", | ||
75 | "InstallExecuteSequence:ProcessComponents\t\t1600", | ||
76 | "InstallExecuteSequence:PublishFeatures\t\t6300", | ||
77 | "InstallExecuteSequence:PublishProduct\t\t6400", | ||
78 | "InstallExecuteSequence:RegisterProduct\t\t6100", | ||
79 | "InstallExecuteSequence:RegisterUser\t\t6000", | ||
80 | "InstallExecuteSequence:RemoveExistingProducts\t\t1401", | ||
81 | "InstallExecuteSequence:RemoveFiles\t\t3500", | ||
82 | "InstallExecuteSequence:RemoveFolders\t\t3600", | ||
83 | "InstallExecuteSequence:UnpublishFeatures\t\t1800", | ||
84 | "InstallExecuteSequence:ValidateProductID\t\t700", | ||
85 | "InstallUISequence:CostFinalize\t\t1000", | ||
86 | "InstallUISequence:CostInitialize\t\t800", | ||
87 | "InstallUISequence:ExecuteAction\t\t1300", | ||
88 | "InstallUISequence:FileCost\t\t900", | ||
89 | "InstallUISequence:FindRelatedProducts\t\t25", | ||
90 | "InstallUISequence:LaunchConditions\t\t100", | ||
91 | "InstallUISequence:MigrateFeatureStates\t\t1200", | ||
92 | "InstallUISequence:ValidateProductID\t\t700", | ||
93 | }, results); | ||
94 | } | ||
95 | |||
96 | private static string[] BuildAndQueryMsi(DisposableFileSystem fs, string sourceFile) | ||
97 | { | ||
98 | var folder = TestData.Get(@"TestData"); | ||
99 | |||
100 | var baseFolder = fs.GetFolder(); | ||
101 | var intermediateFolder = Path.Combine(baseFolder, "obj"); | ||
102 | var msiPath = Path.Combine(baseFolder, "bin", "test.msi"); | ||
103 | |||
104 | var result = WixRunner.Execute(new[] | ||
105 | { | ||
106 | "build", | ||
107 | Path.Combine(folder, "StandardAction", sourceFile), | ||
108 | "-bindpath", Path.Combine(folder, "SingleFile", "data"), | ||
109 | "-intermediateFolder", intermediateFolder, | ||
110 | "-o", msiPath | ||
111 | }); | ||
112 | |||
113 | result.AssertSuccess(); | ||
114 | |||
115 | var results = Query.QueryDatabase(msiPath, new[] | ||
116 | { | ||
117 | "InstallExecuteSequence", | ||
118 | "InstallUISequence" | ||
119 | }).ToArray(); | ||
120 | |||
121 | return results; | ||
122 | } | ||
123 | } | ||
124 | } | ||
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/StandardAction/SpecialActionOverride.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/StandardAction/SpecialActionOverride.wxs new file mode 100644 index 00000000..e10538c1 --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/StandardAction/SpecialActionOverride.wxs | |||
@@ -0,0 +1,11 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | ||
2 | <Package Name="~SpecialActionOverride" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a" | ||
3 | Compressed="no"> | ||
4 | <File Source="test.txt" /> | ||
5 | |||
6 | <InstallExecuteSequence> | ||
7 | <FindRelatedProducts Before="LaunchConditions" /> | ||
8 | <AppSearch After="FindRelatedProducts" /> | ||
9 | </InstallExecuteSequence> | ||
10 | </Package> | ||
11 | </Wix> | ||
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/StandardAction/StandardActionOverride.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/StandardAction/StandardActionOverride.wxs new file mode 100644 index 00000000..2965014e --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/StandardAction/StandardActionOverride.wxs | |||
@@ -0,0 +1,10 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | ||
2 | <Package Name="~StandardActionOverride" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a" | ||
3 | Compressed="no"> | ||
4 | <File Source="test.txt" /> | ||
5 | |||
6 | <InstallExecuteSequence> | ||
7 | <InstallFiles Condition="TEST_CONDITION" /> | ||
8 | </InstallExecuteSequence> | ||
9 | </Package> | ||
10 | </Wix> | ||