diff options
author | Bob Arnson <bob@firegiant.com> | 2023-12-23 21:37:02 -0500 |
---|---|---|
committer | Bob Arnson <github@bobs.org> | 2023-12-30 18:00:56 -0500 |
commit | 1eea9c6e7b276c7c0dfde7779dfec45046ad5831 (patch) | |
tree | 487929fdae1e827722d951f97447b185a4d73148 | |
parent | f4a0522fde6066c76e771f6be381bf9e658b875a (diff) | |
download | wix-1eea9c6e7b276c7c0dfde7779dfec45046ad5831.tar.gz wix-1eea9c6e7b276c7c0dfde7779dfec45046ad5831.tar.bz2 wix-1eea9c6e7b276c7c0dfde7779dfec45046ad5831.zip |
Add default major upgrade.
Add Package/@UpgradeStrategy to allow `none` to suppress major upgrade.
Implements https://github.com/wixtoolset/issues/issues/7605.
Requires https://github.com/wixtoolset/wix/pull/435.
9 files changed, 164 insertions, 5 deletions
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixPackageSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixPackageSymbol.cs index e1720033..4a112266 100644 --- a/src/api/wix/WixToolset.Data/Symbols/WixPackageSymbol.cs +++ b/src/api/wix/WixToolset.Data/Symbols/WixPackageSymbol.cs | |||
@@ -46,6 +46,12 @@ namespace WixToolset.Data.Symbols | |||
46 | PerMachine = 0x1, | 46 | PerMachine = 0x1, |
47 | } | 47 | } |
48 | 48 | ||
49 | public enum WixPackageUpgradeStrategy | ||
50 | { | ||
51 | None = 0x0, | ||
52 | MajorUpgrade = 0x1, | ||
53 | } | ||
54 | |||
49 | public class WixPackageSymbol : IntermediateSymbol | 55 | public class WixPackageSymbol : IntermediateSymbol |
50 | { | 56 | { |
51 | public WixPackageSymbol() : base(SymbolDefinitions.WixPackage, null, null) | 57 | public WixPackageSymbol() : base(SymbolDefinitions.WixPackage, null, null) |
@@ -106,6 +112,12 @@ namespace WixToolset.Data.Symbols | |||
106 | set => this.Set((int)WixPackageSymbolFields.Codepage, value); | 112 | set => this.Set((int)WixPackageSymbolFields.Codepage, value); |
107 | } | 113 | } |
108 | 114 | ||
115 | public WixPackageUpgradeStrategy UpgradeStrategy | ||
116 | { | ||
117 | get => (WixPackageUpgradeStrategy)this.Fields[(int)WixPackageSymbolFields.Attributes].AsNumber(); | ||
118 | set => this.Set((int)WixPackageSymbolFields.Attributes, (int)value); | ||
119 | } | ||
120 | |||
109 | public bool PerMachine => (this.Attributes & WixPackageAttributes.PerMachine) == WixPackageAttributes.PerMachine; | 121 | public bool PerMachine => (this.Attributes & WixPackageAttributes.PerMachine) == WixPackageAttributes.PerMachine; |
110 | } | 122 | } |
111 | } | 123 | } |
diff --git a/src/api/wix/WixToolset.Data/WixStandardLibrary.cs b/src/api/wix/WixToolset.Data/WixStandardLibrary.cs index 3758e5b1..3f851f09 100644 --- a/src/api/wix/WixToolset.Data/WixStandardLibrary.cs +++ b/src/api/wix/WixToolset.Data/WixStandardLibrary.cs | |||
@@ -32,7 +32,17 @@ namespace WixToolset.Data | |||
32 | 32 | ||
33 | private static IEnumerable<Localization> YieldLocalizations() | 33 | private static IEnumerable<Localization> YieldLocalizations() |
34 | { | 34 | { |
35 | var strings = new BindVariable[0]; | 35 | var sourceLineNumber = new SourceLineNumber("wixstd.wixlib"); |
36 | |||
37 | var strings = new[] { | ||
38 | new BindVariable() | ||
39 | { | ||
40 | SourceLineNumbers = sourceLineNumber, | ||
41 | Id = "WixDowngradePreventedMessage", | ||
42 | Value = "A newer version of [ProductName] is already installed.", | ||
43 | Overridable = true, | ||
44 | }, | ||
45 | }; | ||
36 | 46 | ||
37 | var localizedControls = new LocalizedControl[0]; | 47 | var localizedControls = new LocalizedControl[0]; |
38 | 48 | ||
diff --git a/src/api/wix/WixToolset.Data/WixStandardLibraryIdentifiers.cs b/src/api/wix/WixToolset.Data/WixStandardLibraryIdentifiers.cs index 6579a42b..73e4245b 100644 --- a/src/api/wix/WixToolset.Data/WixStandardLibraryIdentifiers.cs +++ b/src/api/wix/WixToolset.Data/WixStandardLibraryIdentifiers.cs | |||
@@ -21,5 +21,10 @@ namespace WixToolset.Data | |||
21 | /// Default feature name. | 21 | /// Default feature name. |
22 | /// </summary> | 22 | /// </summary> |
23 | public static readonly string DefaultFeatureName = "WixDefaultFeature"; | 23 | public static readonly string DefaultFeatureName = "WixDefaultFeature"; |
24 | |||
25 | /// <summary> | ||
26 | /// WiX Standard localization strings. | ||
27 | /// </summary> | ||
28 | public static readonly string WixStandardLocalizationStrings = "WixStandardLocalizationStrings"; | ||
24 | } | 29 | } |
25 | } | 30 | } |
diff --git a/src/wix/WixToolset.Core/Compiler_Package.cs b/src/wix/WixToolset.Core/Compiler_Package.cs index 17a6a913..31b8e81c 100644 --- a/src/wix/WixToolset.Core/Compiler_Package.cs +++ b/src/wix/WixToolset.Core/Compiler_Package.cs | |||
@@ -41,6 +41,7 @@ namespace WixToolset.Core | |||
41 | var isPackageNameSet = false; | 41 | var isPackageNameSet = false; |
42 | var isKeywordsSet = false; | 42 | var isKeywordsSet = false; |
43 | var isPackageAuthorSet = false; | 43 | var isPackageAuthorSet = false; |
44 | var upgradeStrategy = WixPackageUpgradeStrategy.MajorUpgrade; | ||
44 | 45 | ||
45 | this.GetDefaultPlatformAndInstallerVersion(out var platform, out var msiVersion); | 46 | this.GetDefaultPlatformAndInstallerVersion(out var platform, out var msiVersion); |
46 | 47 | ||
@@ -111,6 +112,21 @@ namespace WixToolset.Core | |||
111 | case "UpgradeCode": | 112 | case "UpgradeCode": |
112 | upgradeCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); | 113 | upgradeCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); |
113 | break; | 114 | break; |
115 | case "UpgradeStrategy": | ||
116 | var strategy = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
117 | switch (strategy) | ||
118 | { | ||
119 | case "majorUpgrade": | ||
120 | upgradeStrategy = WixPackageUpgradeStrategy.MajorUpgrade; | ||
121 | break; | ||
122 | case "none": | ||
123 | upgradeStrategy = WixPackageUpgradeStrategy.None; | ||
124 | break; | ||
125 | default: | ||
126 | this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, strategy, "majorUpgrade", "none")); | ||
127 | break; | ||
128 | } | ||
129 | break; | ||
114 | case "Version": | 130 | case "Version": |
115 | version = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib); | 131 | version = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib); |
116 | break; | 132 | break; |
@@ -382,6 +398,7 @@ namespace WixToolset.Core | |||
382 | Manufacturer = manufacturer, | 398 | Manufacturer = manufacturer, |
383 | Attributes = isPerMachine ? WixPackageAttributes.PerMachine : WixPackageAttributes.None, | 399 | Attributes = isPerMachine ? WixPackageAttributes.PerMachine : WixPackageAttributes.None, |
384 | Codepage = codepage, | 400 | Codepage = codepage, |
401 | UpgradeStrategy = upgradeStrategy, | ||
385 | }); | 402 | }); |
386 | 403 | ||
387 | if (!isCommentsSet) | 404 | if (!isCommentsSet) |
diff --git a/src/wix/WixToolset.Core/Link/AddDefaultSymbolsCommand.cs b/src/wix/WixToolset.Core/Link/AddDefaultSymbolsCommand.cs index 221b5411..8d9f7cab 100644 --- a/src/wix/WixToolset.Core/Link/AddDefaultSymbolsCommand.cs +++ b/src/wix/WixToolset.Core/Link/AddDefaultSymbolsCommand.cs | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | namespace WixToolset.Core.Link | 3 | namespace WixToolset.Core.Link |
4 | { | 4 | { |
5 | using System; | ||
5 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
6 | using System.Linq; | 7 | using System.Linq; |
7 | using WixToolset.Data; | 8 | using WixToolset.Data; |
@@ -49,20 +50,80 @@ namespace WixToolset.Core.Link | |||
49 | } | 50 | } |
50 | ); | 51 | ); |
51 | } | 52 | } |
53 | |||
54 | var symbols = this.Sections.SelectMany(section => section.Symbols); | ||
55 | var upgradeSymbols = symbols.OfType<UpgradeSymbol>(); | ||
56 | if (!upgradeSymbols.Any()) | ||
57 | { | ||
58 | var packageSymbol = this.Find.EntrySection.Symbols.OfType<WixPackageSymbol>().FirstOrDefault(); | ||
59 | |||
60 | if (packageSymbol?.UpgradeStrategy == WixPackageUpgradeStrategy.MajorUpgrade | ||
61 | && !String.IsNullOrEmpty(packageSymbol?.UpgradeCode)) | ||
62 | { | ||
63 | this.AddDefaultMajorUpgrade(packageSymbol); | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | |||
68 | private void AddDefaultMajorUpgrade(WixPackageSymbol packageSymbol) | ||
69 | { | ||
70 | this.AddSymbols(this.Find.EntrySection, | ||
71 | new UpgradeSymbol(packageSymbol.SourceLineNumbers) | ||
72 | { | ||
73 | UpgradeCode = packageSymbol.UpgradeCode, | ||
74 | MigrateFeatures = true, | ||
75 | ActionProperty = WixUpgradeConstants.UpgradeDetectedProperty, | ||
76 | VersionMax = packageSymbol.Version, | ||
77 | Language = packageSymbol.Language, | ||
78 | }, | ||
79 | new UpgradeSymbol(packageSymbol.SourceLineNumbers) | ||
80 | { | ||
81 | UpgradeCode = packageSymbol.UpgradeCode, | ||
82 | VersionMin = packageSymbol.Version, | ||
83 | Language = packageSymbol.Language, | ||
84 | OnlyDetect = true, | ||
85 | ActionProperty = WixUpgradeConstants.DowngradeDetectedProperty, | ||
86 | }, | ||
87 | new LaunchConditionSymbol(packageSymbol.SourceLineNumbers) | ||
88 | { | ||
89 | Condition = WixUpgradeConstants.DowngradePreventedCondition, | ||
90 | Description = "!(loc.WixDowngradePreventedMessage)", | ||
91 | }, | ||
92 | new WixActionSymbol(packageSymbol.SourceLineNumbers, | ||
93 | new Identifier(AccessModifier.Global, SequenceTable.InstallExecuteSequence, "RemoveExistingProducts")) | ||
94 | { | ||
95 | SequenceTable = SequenceTable.InstallExecuteSequence, | ||
96 | Action = "RemoveExistingProducts", | ||
97 | After = "InstallValidate", | ||
98 | }, | ||
99 | new WixSimpleReferenceSymbol(packageSymbol.SourceLineNumbers) | ||
100 | { | ||
101 | Table = SymbolDefinitions.WixAction.Name, | ||
102 | PrimaryKeys = "InstallExecuteSequence/InstallValidate", | ||
103 | }); | ||
52 | } | 104 | } |
53 | 105 | ||
54 | private void AddSymbolsToNewSection(string sectionId, params IntermediateSymbol[] symbols) | 106 | private void AddSymbolsToNewSection(string sectionId, params IntermediateSymbol[] symbols) |
55 | { | 107 | { |
56 | var section = new IntermediateSection(sectionId, SectionType.Fragment); | 108 | var section = new IntermediateSection(sectionId, SectionType.Fragment); |
109 | |||
57 | this.Sections.Add(section); | 110 | this.Sections.Add(section); |
58 | 111 | ||
112 | this.AddSymbols(section, symbols); | ||
113 | } | ||
114 | |||
115 | private void AddSymbols(IntermediateSection section, params IntermediateSymbol[] symbols) | ||
116 | { | ||
59 | foreach (var symbol in symbols) | 117 | foreach (var symbol in symbols) |
60 | { | 118 | { |
61 | section.AddSymbol(symbol); | 119 | section.AddSymbol(symbol); |
62 | 120 | ||
63 | var symbolWithSection = new SymbolWithSection(section, symbol); | 121 | if (!String.IsNullOrEmpty(symbol.Id?.Id)) |
64 | var fullName = symbolWithSection.GetFullName(); | 122 | { |
65 | this.Find.SymbolsByName.Add(fullName, symbolWithSection); | 123 | var symbolWithSection = new SymbolWithSection(section, symbol); |
124 | var fullName = symbolWithSection.GetFullName(); | ||
125 | this.Find.SymbolsByName.Add(fullName, symbolWithSection); | ||
126 | } | ||
66 | } | 127 | } |
67 | } | 128 | } |
68 | } | 129 | } |
diff --git a/src/wix/WixToolset.Core/Linker.cs b/src/wix/WixToolset.Core/Linker.cs index 32ccb144..a536c049 100644 --- a/src/wix/WixToolset.Core/Linker.cs +++ b/src/wix/WixToolset.Core/Linker.cs | |||
@@ -90,7 +90,7 @@ namespace WixToolset.Core | |||
90 | if (library.Localizations?.Count > 0) | 90 | if (library.Localizations?.Count > 0) |
91 | { | 91 | { |
92 | // Include localizations from the extension data and be sure to note that the localization came from | 92 | // Include localizations from the extension data and be sure to note that the localization came from |
93 | // an extension. It is important to remember whiche localization came from an extension when filtering | 93 | // an extension. It is important to remember which localization came from an extension when filtering |
94 | // localizations during the resolve process later. | 94 | // localizations during the resolve process later. |
95 | localizations.AddRange(library.Localizations.Select(l => l.UpdateLocation(LocalizationLocation.Extension))); | 95 | localizations.AddRange(library.Localizations.Select(l => l.UpdateLocation(LocalizationLocation.Extension))); |
96 | } | 96 | } |
@@ -103,6 +103,11 @@ namespace WixToolset.Core | |||
103 | var stdlib = WixStandardLibrary.Build(this.Context.Platform); | 103 | var stdlib = WixStandardLibrary.Build(this.Context.Platform); |
104 | 104 | ||
105 | sections.AddRange(stdlib.Sections); | 105 | sections.AddRange(stdlib.Sections); |
106 | |||
107 | if (stdlib.Localizations?.Count > 0) | ||
108 | { | ||
109 | localizations.AddRange(stdlib.Localizations); | ||
110 | } | ||
106 | } | 111 | } |
107 | 112 | ||
108 | var multipleFeatureComponents = new Hashtable(); | 113 | var multipleFeatureComponents = new Hashtable(); |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DefaultMajorUpgrade/DefaultMajorUpgrade.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DefaultMajorUpgrade/DefaultMajorUpgrade.wxs new file mode 100644 index 00000000..ce9fd96f --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DefaultMajorUpgrade/DefaultMajorUpgrade.wxs | |||
@@ -0,0 +1,12 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | ||
2 | <Package Name="MajorUpgradeDowngradeMessage" Language="1033" Version="2.0.0" Manufacturer="Example Corporation" UpgradeCode="7ab24276-c628-43db-9e65-a184d052909b" Scope="perMachine"> | ||
3 | <Feature Id="ProductFeature" Title="MsiPackageTitle"> | ||
4 | </Feature> | ||
5 | </Package> | ||
6 | |||
7 | <Fragment> | ||
8 | <StandardDirectory Id="ProgramFiles6432Folder"> | ||
9 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" /> | ||
10 | </StandardDirectory> | ||
11 | </Fragment> | ||
12 | </Wix> | ||
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DefaultMajorUpgradeNone/DefaultMajorUpgradeNone.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DefaultMajorUpgradeNone/DefaultMajorUpgradeNone.wxs new file mode 100644 index 00000000..63ff178b --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DefaultMajorUpgradeNone/DefaultMajorUpgradeNone.wxs | |||
@@ -0,0 +1,12 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | ||
2 | <Package Name="MajorUpgradeDowngradeMessage" UpgradeStrategy="none" Language="1033" Version="2.0.0" Manufacturer="Example Corporation" UpgradeCode="7ab24276-c628-43db-9e65-a184d052909b" Scope="perMachine"> | ||
3 | <Feature Id="ProductFeature" Title="MsiPackageTitle"> | ||
4 | </Feature> | ||
5 | </Package> | ||
6 | |||
7 | <Fragment> | ||
8 | <StandardDirectory Id="ProgramFiles6432Folder"> | ||
9 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" /> | ||
10 | </StandardDirectory> | ||
11 | </Fragment> | ||
12 | </Wix> | ||
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/UpgradeFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/UpgradeFixture.cs index 3d2aa722..1ae74210 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/UpgradeFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/UpgradeFixture.cs | |||
@@ -58,6 +58,31 @@ namespace WixToolsetTest.CoreIntegration | |||
58 | }, results); | 58 | }, results); |
59 | } | 59 | } |
60 | 60 | ||
61 | [Fact] | ||
62 | public void DefaultMajorUpgradePopulatesUpgradeRowsAsExpected() | ||
63 | { | ||
64 | var folder = TestData.Get("TestData", "DefaultMajorUpgrade"); | ||
65 | var build = new Builder(folder, new Type[] { }, new[] { folder }); | ||
66 | |||
67 | var results = build.BuildAndQuery(Build, "Upgrade", "LaunchCondition"); | ||
68 | WixAssert.CompareLineByLine(new[] | ||
69 | { | ||
70 | "LaunchCondition:NOT WIX_DOWNGRADE_DETECTED\tA newer version of [ProductName] is already installed.", | ||
71 | "Upgrade:{7AB24276-C628-43DB-9E65-A184D052909B}\t\t2.0.0\t1033\t1\t\tWIX_UPGRADE_DETECTED", | ||
72 | "Upgrade:{7AB24276-C628-43DB-9E65-A184D052909B}\t2.0.0\t\t1033\t2\t\tWIX_DOWNGRADE_DETECTED", | ||
73 | }, results); | ||
74 | } | ||
75 | |||
76 | [Fact] | ||
77 | public void UpgradeStrategyNoneDoesNotCreateDefaultMajorUpgrade() | ||
78 | { | ||
79 | var folder = TestData.Get("TestData", "DefaultMajorUpgradeNone"); | ||
80 | var build = new Builder(folder, new Type[] { }, new[] { folder }); | ||
81 | |||
82 | var results = build.BuildAndQuery(Build, "Upgrade", "LaunchCondition"); | ||
83 | Assert.Empty(results); | ||
84 | } | ||
85 | |||
61 | private static void Build(string[] args) | 86 | private static void Build(string[] args) |
62 | { | 87 | { |
63 | var result = WixRunner.Execute(args); | 88 | var result = WixRunner.Execute(args); |