Fix ParsePossibleKeyPathExtensionElement extension point to support more than registry
Fixes 7208
Rob Mensching committed
Feb 9, 2023 at 21:59 UTC
b500f7ae7113039c878555ec622d551854f891e2
6 files changed
+211
-7
src/wix/WixToolset.Core/Compiler.cs
+26
-7
@@ -2422,14 +2422,33 @@ namespace WixToolset.Core
2422
{
2423
keyPathSet = possibleKeyPath.Explicit ? YesNoType.Yes : YesNoType.NotSet;
2424
2425
- if (!String.IsNullOrEmpty(possibleKeyPath.Id))
2425
+ switch (possibleKeyPath.Type)
2426
{
2427
- keyPossible = possibleKeyPath.Id;
2428
- }
2429
-
2430
- if (PossibleKeyPathType.Registry == possibleKeyPath.Type || PossibleKeyPathType.RegistryFormatted == possibleKeyPath.Type)
2431
- {
2432
- keyBit = ComponentKeyPathType.Registry; //MsiInterop.MsidbComponentAttributesRegistryKeyPath;
2427
+ case PossibleKeyPathType.File:
2428
+ keyBit = ComponentKeyPathType.File;
2429
+ keyPossible = possibleKeyPath.Id;
2430
+ break;
2431
+ case PossibleKeyPathType.Directory:
2432
+ keyBit = ComponentKeyPathType.Directory;
2433
+ keyPossible = String.Empty;
2434
+ break;
2435
+
2436
+ case PossibleKeyPathType.OdbcDataSource:
2437
+ keyBit = ComponentKeyPathType.OdbcDataSource;
2438
+ keyPossible = possibleKeyPath.Id;
2439
+ break;
2440
+
2441
+ case PossibleKeyPathType.Registry:
2442
+ case PossibleKeyPathType.RegistryFormatted:
2443
+ keyBit = ComponentKeyPathType.Registry;
2444
+ keyPossible = possibleKeyPath.Id;
2445
+ break;
2446
+
2447
+ case PossibleKeyPathType.None:
2448
+ default:
2449
+ keyBit = null;
2450
+ keyPossible = null;
2451
+ break;
2452
}
2453
}
2454
}
src/wix/test/Example.Extension/ExampleCompilerExtension.cs
+72
@@ -7,6 +7,7 @@ namespace Example.Extension
7
using System.Xml.Linq;
8
using WixToolset.Data;
9
using WixToolset.Extensibility;
10
+ using WixToolset.Extensibility.Data;
11
12
internal class ExampleCompilerExtension : BaseCompilerExtension
13
{
@@ -57,6 +58,24 @@ namespace Example.Extension
58
}
59
}
60
61
+ public override IComponentKeyPath ParsePossibleKeyPathElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
62
+ {
63
+ switch (parentElement.Name.LocalName)
64
+ {
65
+ case "Component":
66
+ var componentId = context["ComponentId"];
67
+
68
+ switch (element.Name.LocalName)
69
+ {
70
+ case "ExampleSetKeyPath":
71
+ return this.ParseExampleSetKeyPathElement(intermediate, section, element, componentId);
72
+ }
73
+ break;
74
+ }
75
+
76
+ return base.ParsePossibleKeyPathElement(intermediate, section, parentElement, element, context);
77
+ }
78
+
79
private void ParseExampleElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId)
80
{
81
var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
@@ -101,6 +120,59 @@ namespace Example.Extension
120
}
121
}
122
123
+ private IComponentKeyPath ParseExampleSetKeyPathElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId)
124
+ {
125
+ var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
126
+ string file = null;
127
+ string reg = null;
128
+ var explicitly = false;
129
+
130
+ foreach (var attrib in element.Attributes())
131
+ {
132
+ if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
133
+ {
134
+ switch (attrib.Name.LocalName)
135
+ {
136
+ case "File":
137
+ file = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
138
+ break;
139
+
140
+ case "Registry":
141
+ reg = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
142
+ break;
143
+
144
+ case "Explicitly":
145
+ explicitly = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) == YesNoType.Yes;
146
+ break;
147
+
148
+ default:
149
+ this.ParseHelper.UnexpectedAttribute(element, attrib);
150
+ break;
151
+ }
152
+ }
153
+ else
154
+ {
155
+ this.ParseAttribute(intermediate, section, element, attrib, null);
156
+ }
157
+ }
158
+
159
+ if (file == null && reg == null)
160
+ {
161
+ this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "File", "Registry", true));
162
+ }
163
+
164
+ if (!this.Messaging.EncounteredError)
165
+ {
166
+ var componentKeyPath = this.CreateComponentKeyPath();
167
+ componentKeyPath.Id = file ?? reg;
168
+ componentKeyPath.Explicit = explicitly;
169
+ componentKeyPath.Type = String.IsNullOrEmpty(file) ? PossibleKeyPathType.Registry : PossibleKeyPathType.File;
170
+ return componentKeyPath;
171
+ }
172
+
173
+ return null;
174
+ }
175
+
176
private void ParseExampleEnsureTableElement(Intermediate intermediate, IntermediateSection section, XElement element)
177
{
178
var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
src/wix/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs
+60
@@ -96,6 +96,66 @@ namespace WixToolsetTest.CoreIntegration
96
}
97
}
98
99
+ [Fact]
100
+ public void CanBuildWithExampleExtensionWithFilePossibleKeyPath()
101
+ {
102
+ var folder = TestData.Get("TestData", "ExampleExtensionUsingPossibleKeyPath");
103
+
104
+ using (var fs = new DisposableFileSystem())
105
+ {
106
+ var intermediateFolder = fs.GetFolder();
107
+
108
+ var result = WixRunner.Execute(new[]
109
+ {
110
+ "build",
111
+ Path.Combine(folder, "PackageWithFile.wxs"),
112
+ "-ext", ExtensionPaths.ExampleExtensionPath,
113
+ "-bindpath", Path.Combine(folder, "data"),
114
+ "-intermediateFolder", intermediateFolder,
115
+ "-o", Path.Combine(intermediateFolder, "bin", "extest.msi")
116
+ });
117
+
118
+ result.AssertSuccess();
119
+
120
+ var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, "bin", "extest.wixpdb"));
121
+ var section = intermediate.Sections.Single();
122
+
123
+ var componentSymbol = section.Symbols.OfType<ComponentSymbol>().Single();
124
+ Assert.Equal("ExampleFile", componentSymbol.KeyPath);
125
+ Assert.Equal(ComponentKeyPathType.File, componentSymbol.KeyPathType);
126
+ }
127
+ }
128
+
129
+ [Fact]
130
+ public void CanBuildWithExampleExtensionWithRegistryPossibleKeyPath()
131
+ {
132
+ var folder = TestData.Get("TestData", "ExampleExtensionUsingPossibleKeyPath");
133
+
134
+ using (var fs = new DisposableFileSystem())
135
+ {
136
+ var intermediateFolder = fs.GetFolder();
137
+
138
+ var result = WixRunner.Execute(new[]
139
+ {
140
+ "build",
141
+ Path.Combine(folder, "PackageWithRegistry.wxs"),
142
+ "-ext", ExtensionPaths.ExampleExtensionPath,
143
+ "-bindpath", Path.Combine(folder, "data"),
144
+ "-intermediateFolder", intermediateFolder,
145
+ "-o", Path.Combine(intermediateFolder, "bin", "extest.msi")
146
+ });
147
+
148
+ result.AssertSuccess();
149
+
150
+ var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, "bin", "extest.wixpdb"));
151
+ var section = intermediate.Sections.Single();
152
+
153
+ var componentSymbol = section.Symbols.OfType<ComponentSymbol>().Single();
154
+ Assert.Equal("RegMadeKeyPath", componentSymbol.KeyPath);
155
+ Assert.Equal(ComponentKeyPathType.Registry, componentSymbol.KeyPathType);
156
+ }
157
+ }
158
+
159
[Fact]
160
public void CanParseCommandLineWithExtension()
161
{
src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExampleExtensionUsingPossibleKeyPath/PackageWithFile.wxs
new
+27
@@ -0,0 +1,27 @@
1
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
2
+ xmlns:ex="http://www.example.com/scheams/v1/wxs">
3
+ <Package Name="MsiPackage" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a" Compressed="no">
4
+ <MajorUpgrade DowngradeErrorMessage="Don't upgrade" />
5
+
6
+ <Feature Id="ProductFeature">
7
+ <ComponentGroupRef Id="ProductComponents" />
8
+ </Feature>
9
+ </Package>
10
+
11
+ <Fragment>
12
+ <StandardDirectory Id="ProgramFilesFolder">
13
+ <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
14
+ </StandardDirectory>
15
+ </Fragment>
16
+
17
+ <Fragment>
18
+ <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
19
+ <Component>
20
+ <RegistryValue Id="RegMadeKeyPath" Root="HKLM" Key="SOFTWARE\Example Corporation" Name="Test" Value="Thing" />
21
+
22
+ <ex:ExampleSetKeyPath File="ExampleFile" Explicitly="yes" />
23
+ <File Id="ExampleFile" Source="example.txt" />
24
+ </Component>
25
+ </ComponentGroup>
26
+ </Fragment>
27
+</Wix>
src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExampleExtensionUsingPossibleKeyPath/PackageWithRegistry.wxs
new
+25
@@ -0,0 +1,25 @@
1
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
2
+ xmlns:ex="http://www.example.com/scheams/v1/wxs">
3
+ <Package Name="MsiPackage With Registry" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a" Compressed="no">
4
+ <MajorUpgrade DowngradeErrorMessage="Don't upgrade" />
5
+
6
+ <Feature Id="ProductFeature">
7
+ <ComponentGroupRef Id="ProductComponents" />
8
+ </Feature>
9
+ </Package>
10
+
11
+ <Fragment>
12
+ <StandardDirectory Id="ProgramFilesFolder">
13
+ <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
14
+ </StandardDirectory>
15
+ </Fragment>
16
+
17
+ <Fragment>
18
+ <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
19
+ <Component>
20
+ <ex:ExampleSetKeyPath Registry="RegMadeKeyPath" />
21
+ <RegistryValue Id="RegMadeKeyPath" Root="HKLM" Key="SOFTWARE\Example Corporation" Name="Test" Value="Thing" KeyPath="no" />
22
+ </Component>
23
+ </ComponentGroup>
24
+ </Fragment>
25
+</Wix>
src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExampleExtensionUsingPossibleKeyPath/data/example.txt
new
+1
@@ -0,0 +1 @@
1
+This is example.txt.