aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ca/XmlConfig.cpp101
-rw-r--r--src/test/WixToolsetTest.Util/TestData/XmlConfig/Package.en-us.wxl11
-rw-r--r--src/test/WixToolsetTest.Util/TestData/XmlConfig/Package.wxs27
-rw-r--r--src/test/WixToolsetTest.Util/TestData/XmlConfigModule/Module.wxs34
-rw-r--r--src/test/WixToolsetTest.Util/TestData/XmlConfigModule/my.xml1
-rw-r--r--src/test/WixToolsetTest.Util/UtilExtensionFixture.cs27
-rw-r--r--src/test/WixToolsetTest.Util/WixToolsetTest.Util.csproj36
-rw-r--r--src/wixext/Symbols/XmlConfigSymbol.cs8
-rw-r--r--src/wixext/UtilCompiler.cs4
-rw-r--r--src/wixext/UtilTableDefinitions.cs3
10 files changed, 175 insertions, 77 deletions
diff --git a/src/ca/XmlConfig.cpp b/src/ca/XmlConfig.cpp
index afd3dafb..0c2fae37 100644
--- a/src/ca/XmlConfig.cpp
+++ b/src/ca/XmlConfig.cpp
@@ -30,10 +30,10 @@ enum eXmlPreserveDate
30}; 30};
31 31
32LPCWSTR vcsXmlConfigQuery = 32LPCWSTR vcsXmlConfigQuery =
33 L"SELECT `Wix4XmlConfig`.`Wix4XmlConfig`, `Wix4XmlConfig`.`File`, `Wix4XmlConfig`.`ElementPath`, `Wix4XmlConfig`.`VerifyPath`, `Wix4XmlConfig`.`Name`, " 33 L"SELECT `Wix4XmlConfig`.`Wix4XmlConfig`, `Wix4XmlConfig`.`File`, `Wix4XmlConfig`.`ElementId`, `Wix4XmlConfig`.`ElementPath`, `Wix4XmlConfig`.`VerifyPath`, `Wix4XmlConfig`.`Name`, "
34 L"`Wix4XmlConfig`.`Value`, `Wix4XmlConfig`.`Flags`, `Wix4XmlConfig`.`Component_`, `Component`.`Attributes` " 34 L"`Wix4XmlConfig`.`Value`, `Wix4XmlConfig`.`Flags`, `Wix4XmlConfig`.`Component_`, `Component`.`Attributes` "
35 L"FROM `Wix4XmlConfig`,`Component` WHERE `Wix4XmlConfig`.`Component_`=`Component`.`Component` ORDER BY `File`, `Sequence`"; 35 L"FROM `Wix4XmlConfig`,`Component` WHERE `Wix4XmlConfig`.`Component_`=`Component`.`Component` ORDER BY `File`, `Sequence`";
36enum eXmlConfigQuery { xfqXmlConfig = 1, xfqFile, xfqElementPath, xfqVerifyPath, xfqName, xfqValue, xfqXmlFlags, xfqComponent, xfqCompAttributes }; 36enum eXmlConfigQuery { xfqXmlConfig = 1, xfqFile, xfqElementId, xfqElementPath, xfqVerifyPath, xfqName, xfqValue, xfqXmlFlags, xfqComponent, xfqCompAttributes };
37 37
38struct XML_CONFIG_CHANGE 38struct XML_CONFIG_CHANGE
39{ 39{
@@ -44,6 +44,7 @@ struct XML_CONFIG_CHANGE
44 INSTALLSTATE isAction; 44 INSTALLSTATE isAction;
45 45
46 WCHAR wzFile[MAX_PATH]; 46 WCHAR wzFile[MAX_PATH];
47 LPWSTR pwzElementId;
47 LPWSTR pwzElementPath; 48 LPWSTR pwzElementPath;
48 LPWSTR pwzVerifyPath; 49 LPWSTR pwzVerifyPath;
49 WCHAR wzName[MAX_DARWIN_COLUMN]; 50 WCHAR wzName[MAX_DARWIN_COLUMN];
@@ -72,26 +73,32 @@ static HRESULT FreeXmlConfigChangeList(
72 pxfcDelete = pxfcList; 73 pxfcDelete = pxfcList;
73 pxfcList = pxfcList->pxfcNext; 74 pxfcList = pxfcList->pxfcNext;
74 75
76 if (pxfcDelete->pwzElementId)
77 {
78 hr = MemFree(pxfcDelete->pwzElementId);
79 ExitOnFailure(hr, "failed to free xml config element id in change list item");
80 }
81
75 if (pxfcDelete->pwzElementPath) 82 if (pxfcDelete->pwzElementPath)
76 { 83 {
77 hr = MemFree(pxfcDelete->pwzElementPath); 84 hr = MemFree(pxfcDelete->pwzElementPath);
78 ExitOnFailure(hr, "failed to free xml file element path in change list item"); 85 ExitOnFailure(hr, "failed to free xml config element path in change list item");
79 } 86 }
80 87
81 if (pxfcDelete->pwzVerifyPath) 88 if (pxfcDelete->pwzVerifyPath)
82 { 89 {
83 hr = MemFree(pxfcDelete->pwzVerifyPath); 90 hr = MemFree(pxfcDelete->pwzVerifyPath);
84 ExitOnFailure(hr, "failed to free xml file verify path in change list item"); 91 ExitOnFailure(hr, "failed to free xml config verify path in change list item");
85 } 92 }
86 93
87 if (pxfcDelete->pwzValue) 94 if (pxfcDelete->pwzValue)
88 { 95 {
89 hr = MemFree(pxfcDelete->pwzValue); 96 hr = MemFree(pxfcDelete->pwzValue);
90 ExitOnFailure(hr, "failed to free xml file value in change list item"); 97 ExitOnFailure(hr, "failed to free xml config value in change list item");
91 } 98 }
92 99
93 hr = MemFree(pxfcDelete); 100 hr = MemFree(pxfcDelete);
94 ExitOnFailure(hr, "failed to free xml file change list item"); 101 ExitOnFailure(hr, "failed to free xml config change list item");
95 } 102 }
96 103
97LExit: 104LExit:
@@ -191,6 +198,10 @@ static HRESULT ReadXmlConfigTable(
191 hr = WcaGetRecordInteger(hRec, xfqXmlFlags, &(*ppxfcTail)->iXmlFlags); 198 hr = WcaGetRecordInteger(hRec, xfqXmlFlags, &(*ppxfcTail)->iXmlFlags);
192 ExitOnFailure(hr, "failed to get Wix4XmlConfig flags for Wix4XmlConfig: %ls", (*ppxfcTail)->wzId); 199 ExitOnFailure(hr, "failed to get Wix4XmlConfig flags for Wix4XmlConfig: %ls", (*ppxfcTail)->wzId);
193 200
201 // Get the Element Id
202 hr = WcaGetRecordFormattedString(hRec, xfqElementId, &(*ppxfcTail)->pwzElementId);
203 ExitOnFailure(hr, "failed to get Element Id for Wix4XmlConfig: %ls", (*ppxfcTail)->wzId);
204
194 // Get the Element Path 205 // Get the Element Path
195 hr = WcaGetRecordFormattedString(hRec, xfqElementPath, &(*ppxfcTail)->pwzElementPath); 206 hr = WcaGetRecordFormattedString(hRec, xfqElementPath, &(*ppxfcTail)->pwzElementPath);
196 ExitOnFailure(hr, "failed to get Element Path for Wix4XmlConfig: %ls", (*ppxfcTail)->wzId); 207 ExitOnFailure(hr, "failed to get Element Path for Wix4XmlConfig: %ls", (*ppxfcTail)->wzId);
@@ -259,45 +270,55 @@ static HRESULT ProcessChanges(
259 pxfcCheck = *ppxfcHead; 270 pxfcCheck = *ppxfcHead;
260 while (pxfcCheck) 271 while (pxfcCheck)
261 { 272 {
262 if (0 == lstrcmpW(pxfc->pwzElementPath, pxfcCheck->wzId) && 0 == pxfc->iXmlFlags 273 if (pxfc->pwzElementId)
263 && XMLCONFIG_CREATE & pxfcCheck->iXmlFlags && XMLCONFIG_ELEMENT & pxfcCheck->iXmlFlags)
264 { 274 {
265 // We found a match. First, take it out of the current list 275 if (0 == lstrcmpW(pxfc->pwzElementId, pxfcCheck->wzId)
266 if (pxfc->pxfcPrev) 276 && 0 == pxfc->iXmlFlags
277 && XMLCONFIG_CREATE & pxfcCheck->iXmlFlags
278 && XMLCONFIG_ELEMENT & pxfcCheck->iXmlFlags)
267 { 279 {
268 pxfc->pxfcPrev->pxfcNext = pxfc->pxfcNext; 280 // We found a match. First, take it out of the current list
269 } 281 if (pxfc->pxfcPrev)
270 else // it was the head. Update the head 282 {
271 { 283 pxfc->pxfcPrev->pxfcNext = pxfc->pxfcNext;
272 *ppxfcHead = pxfc->pxfcNext; 284 }
273 } 285 else // it was the head. Update the head
286 {
287 *ppxfcHead = pxfc->pxfcNext;
288 }
274 289
275 if (pxfc->pxfcNext) 290 if (pxfc->pxfcNext)
276 { 291 {
277 pxfc->pxfcNext->pxfcPrev = pxfc->pxfcPrev; 292 pxfc->pxfcNext->pxfcPrev = pxfc->pxfcPrev;
278 } 293 }
279 294
280 pxfc->pxfcNext = NULL; 295 pxfc->pxfcNext = NULL;
281 pxfc->pxfcPrev = NULL; 296 pxfc->pxfcPrev = NULL;
282 297
283 // Now, add this node to the end of the matched node's additional changes list 298 // Now, add this node to the end of the matched node's additional changes list
284 if (!pxfcCheck->pxfcAdditionalChanges) 299 if (!pxfcCheck->pxfcAdditionalChanges)
285 { 300 {
286 pxfcCheck->pxfcAdditionalChanges = pxfc; 301 pxfcCheck->pxfcAdditionalChanges = pxfc;
287 pxfcCheck->cAdditionalChanges = 1; 302 pxfcCheck->cAdditionalChanges = 1;
303 }
304 else
305 {
306 pxfcLast = pxfcCheck->pxfcAdditionalChanges;
307 cAdditionalChanges = 1;
308 while (pxfcLast->pxfcNext)
309 {
310 pxfcLast = pxfcLast->pxfcNext;
311 ++cAdditionalChanges;
312 }
313 pxfcLast->pxfcNext = pxfc;
314 pxfc->pxfcPrev = pxfcLast;
315 pxfcCheck->cAdditionalChanges = ++cAdditionalChanges;
316 }
288 } 317 }
289 else 318 else
290 { 319 {
291 pxfcLast = pxfcCheck->pxfcAdditionalChanges; 320 hr = E_NOTFOUND;
292 cAdditionalChanges = 1; 321 ExitOnRootFailure(hr, "failed to find matching ElementId: %ls", pxfc->pwzElementId);
293 while (pxfcLast->pxfcNext)
294 {
295 pxfcLast = pxfcLast->pxfcNext;
296 ++cAdditionalChanges;
297 }
298 pxfcLast->pxfcNext = pxfc;
299 pxfc->pxfcPrev = pxfcLast;
300 pxfcCheck->cAdditionalChanges = ++cAdditionalChanges;
301 } 322 }
302 } 323 }
303 324
@@ -381,9 +402,10 @@ static HRESULT WriteChangeData(
381 402
382 HRESULT hr = S_OK; 403 HRESULT hr = S_OK;
383 XML_CONFIG_CHANGE* pxfcAdditionalChanges = NULL; 404 XML_CONFIG_CHANGE* pxfcAdditionalChanges = NULL;
405 LPCWSTR wzElementPath = pxfc->pwzElementId ? pxfc->pwzElementId : pxfc->pwzElementPath;
384 406
385 hr = WcaWriteStringToCaData(pxfc->pwzElementPath, ppwzCustomActionData); 407 hr = WcaWriteStringToCaData(wzElementPath, ppwzCustomActionData);
386 ExitOnFailure(hr, "failed to write ElementPath to custom action data: %ls", pxfc->pwzElementPath); 408 ExitOnFailure(hr, "failed to write ElementPath to custom action data: %ls", wzElementPath);
387 409
388 hr = WcaWriteStringToCaData(pxfc->pwzVerifyPath, ppwzCustomActionData); 410 hr = WcaWriteStringToCaData(pxfc->pwzVerifyPath, ppwzCustomActionData);
389 ExitOnFailure(hr, "failed to write VerifyPath to custom action data: %ls", pxfc->pwzVerifyPath); 411 ExitOnFailure(hr, "failed to write VerifyPath to custom action data: %ls", pxfc->pwzVerifyPath);
@@ -1111,4 +1133,3 @@ LExit:
1111 } 1133 }
1112 return WcaFinalize(er); 1134 return WcaFinalize(er);
1113} 1135}
1114
diff --git a/src/test/WixToolsetTest.Util/TestData/XmlConfig/Package.en-us.wxl b/src/test/WixToolsetTest.Util/TestData/XmlConfig/Package.en-us.wxl
new file mode 100644
index 00000000..38c12ac1
--- /dev/null
+++ b/src/test/WixToolsetTest.Util/TestData/XmlConfig/Package.en-us.wxl
@@ -0,0 +1,11 @@
1<?xml version="1.0" encoding="utf-8"?>
2
3<!--
4This file contains the declaration of all the localizable strings.
5-->
6<WixLocalization xmlns="http://wixtoolset.org/schemas/v4/wxl" Culture="en-US">
7
8 <String Id="DowngradeError">A newer version of [ProductName] is already installed.</String>
9 <String Id="FeatureTitle">MsiPackage</String>
10
11</WixLocalization>
diff --git a/src/test/WixToolsetTest.Util/TestData/XmlConfig/Package.wxs b/src/test/WixToolsetTest.Util/TestData/XmlConfig/Package.wxs
new file mode 100644
index 00000000..21f75f8f
--- /dev/null
+++ b/src/test/WixToolsetTest.Util/TestData/XmlConfig/Package.wxs
@@ -0,0 +1,27 @@
1<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
2 <Package Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
3 <MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" />
4
5 <Feature Id="ProductFeature" Title="!(loc.FeatureTitle)">
6 <Component Id="Del" Directory="INSTALLFOLDER" Guid="3613414c-11f5-40fa-a1f1-a0ba722a6895">
7 <util:XmlConfig
8 Id="DelElement"
9 File="[INSTALLFOLDER]my.xml"
10 Action="delete"
11 Node="element"
12 VerifyPath="xxx"
13 ElementPath="//root/sub"
14 On="install"
15 Sequence="1" />
16 </Component>
17 </Feature>
18 </Package>
19
20 <Fragment>
21 <Directory Id="TARGETDIR" Name="SourceDir">
22 <Directory Id="ProgramFilesFolder">
23 <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
24 </Directory>
25 </Directory>
26 </Fragment>
27</Wix>
diff --git a/src/test/WixToolsetTest.Util/TestData/XmlConfigModule/Module.wxs b/src/test/WixToolsetTest.Util/TestData/XmlConfigModule/Module.wxs
new file mode 100644
index 00000000..93f5eeb1
--- /dev/null
+++ b/src/test/WixToolsetTest.Util/TestData/XmlConfigModule/Module.wxs
@@ -0,0 +1,34 @@
1<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
2 <Module Id="XmlConfigModule" Language="1033" Version="1.0.0.0" Guid="047730a5-30fe-4a62-a520-da9381b8226a">
3
4 <Component Id="Parent" Directory="INSTALLFOLDER">
5 <File Id="my.xml" Source="my.xml" />
6 <util:XmlConfig
7 Id="AddElement"
8 File="[my.xml]"
9 Action="create"
10 Node="element"
11 VerifyPath="xxx"
12 ElementPath="//root/sub"
13 On="install"
14 Sequence="1" />
15 </Component>
16
17 <Component Id="Child" Directory="INSTALLFOLDER" Guid="4613414c-11f5-40fa-a1f1-a0ba722a6895">
18 <util:XmlConfig
19 Id="ChildElement"
20 File="[my.xml]"
21 VerifyPath="xxx"
22 ElementId="AddElement"
23 Sequence="1" />
24 </Component>
25 </Module>
26
27 <Fragment>
28 <Directory Id="TARGETDIR" Name="SourceDir">
29 <Directory Id="ProgramFilesFolder">
30 <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
31 </Directory>
32 </Directory>
33 </Fragment>
34</Wix>
diff --git a/src/test/WixToolsetTest.Util/TestData/XmlConfigModule/my.xml b/src/test/WixToolsetTest.Util/TestData/XmlConfigModule/my.xml
new file mode 100644
index 00000000..bad25217
--- /dev/null
+++ b/src/test/WixToolsetTest.Util/TestData/XmlConfigModule/my.xml
@@ -0,0 +1 @@
This is my.xml file.
diff --git a/src/test/WixToolsetTest.Util/UtilExtensionFixture.cs b/src/test/WixToolsetTest.Util/UtilExtensionFixture.cs
index a32a7d62..d9440614 100644
--- a/src/test/WixToolsetTest.Util/UtilExtensionFixture.cs
+++ b/src/test/WixToolsetTest.Util/UtilExtensionFixture.cs
@@ -173,6 +173,33 @@ namespace WixToolsetTest.Util
173 } 173 }
174 174
175 [Fact] 175 [Fact]
176 public void CanBuildWithXmlConfig()
177 {
178 var folder = TestData.Get(@"TestData", "XmlConfig");
179 var build = new Builder(folder, typeof(UtilExtensionFactory), new[] { folder });
180
181 var results = build.BuildAndQuery(BuildX64, "Wix4XmlConfig");
182 WixAssert.CompareLineByLine(new[]
183 {
184 "Wix4XmlConfig:DelElement\t[INSTALLFOLDER]my.xml\t\t//root/sub\txxx\t\t\t289\tDel\t1",
185 }, results.OrderBy(s => s).ToArray());
186 }
187
188 [Fact]
189 public void CanBuildModuleWithXmlConfig()
190 {
191 var folder = TestData.Get(@"TestData", "XmlConfigModule");
192 var build = new Builder(folder, typeof(UtilExtensionFactory), new[] { folder });
193
194 var results = build.BuildAndQuery(BuildX64, "Wix4XmlConfig");
195 WixAssert.CompareLineByLine(new[]
196 {
197 "Wix4XmlConfig:AddElement.047730A5_30FE_4A62_A520_DA9381B8226A\t[my.xml.047730A5_30FE_4A62_A520_DA9381B8226A]\t\t//root/sub\txxx\t\t\t273\tParent.047730A5_30FE_4A62_A520_DA9381B8226A\t1",
198 "Wix4XmlConfig:ChildElement.047730A5_30FE_4A62_A520_DA9381B8226A\t[my.xml.047730A5_30FE_4A62_A520_DA9381B8226A]\tAddElement.047730A5_30FE_4A62_A520_DA9381B8226A\t\txxx\t\t\t0\tChild.047730A5_30FE_4A62_A520_DA9381B8226A\t1",
199 }, results.OrderBy(s => s).ToArray());
200 }
201
202 [Fact]
176 public void CanBuildBundleWithSearches() 203 public void CanBuildBundleWithSearches()
177 { 204 {
178 var burnStubPath = TestData.Get(@"TestData\.Data\burn.exe"); 205 var burnStubPath = TestData.Get(@"TestData\.Data\burn.exe");
diff --git a/src/test/WixToolsetTest.Util/WixToolsetTest.Util.csproj b/src/test/WixToolsetTest.Util/WixToolsetTest.Util.csproj
index 50776c2c..e77ecbed 100644
--- a/src/test/WixToolsetTest.Util/WixToolsetTest.Util.csproj
+++ b/src/test/WixToolsetTest.Util/WixToolsetTest.Util.csproj
@@ -12,41 +12,7 @@
12 </PropertyGroup> 12 </PropertyGroup>
13 13
14 <ItemGroup> 14 <ItemGroup>
15 <Content Include="TestData\.Data\burn.exe" CopyToOutputDirectory="PreserveNewest" /> 15 <Content Include="TestData\**" CopyToOutputDirectory="PreserveNewest" />
16 <Content Include="TestData\BundleWithSearches\data\fakeba.dll" CopyToOutputDirectory="PreserveNewest" />
17 <Content Include="TestData\BundleWithSearches\data\MsiPackage\Shared.dll" CopyToOutputDirectory="PreserveNewest" />
18 <Content Include="TestData\BundleWithSearches\data\MsiPackage\test.txt" CopyToOutputDirectory="PreserveNewest" />
19 <Content Include="TestData\BundleWithSearches\data\test.msi" CopyToOutputDirectory="PreserveNewest" />
20 <Content Include="TestData\BundleWithSearches\Bundle.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
21 <Content Include="TestData\BundleWithSearches\Bundle.wxs" CopyToOutputDirectory="PreserveNewest" />
22 <Content Include="TestData\UsingFileShare\example.txt" CopyToOutputDirectory="PreserveNewest" />
23 <Content Include="TestData\UsingFileShare\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
24 <Content Include="TestData\UsingFileShare\Package.wxs" CopyToOutputDirectory="PreserveNewest" />
25 <Content Include="TestData\UsingFileShare\PackageComponents.wxs" CopyToOutputDirectory="PreserveNewest" />
26 <Content Include="TestData\CloseApplication\example.txt" CopyToOutputDirectory="PreserveNewest" />
27 <Content Include="TestData\CloseApplication\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
28 <Content Include="TestData\CloseApplication\Package.wxs" CopyToOutputDirectory="PreserveNewest" />
29 <Content Include="TestData\CloseApplication\PackageComponents.wxs" CopyToOutputDirectory="PreserveNewest" />
30 <Content Include="TestData\InternetShortcut\Package.ico" CopyToOutputDirectory="PreserveNewest" />
31 <Content Include="TestData\InternetShortcut\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
32 <Content Include="TestData\InternetShortcut\Package.wxs" CopyToOutputDirectory="PreserveNewest" />
33 <Content Include="TestData\InternetShortcut\PackageComponents.wxs" CopyToOutputDirectory="PreserveNewest" />
34 <Content Include="TestData\InternetShortcutModule\Package.ico" CopyToOutputDirectory="PreserveNewest" />
35 <Content Include="TestData\InternetShortcutModule\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
36 <Content Include="TestData\InternetShortcutModule\Package.wxs" CopyToOutputDirectory="PreserveNewest" />
37 <Content Include="TestData\InternetShortcutModule\PackageComponents.wxs" CopyToOutputDirectory="PreserveNewest" />
38 <Content Include="TestData\PermissionEx\example.txt" CopyToOutputDirectory="PreserveNewest" />
39 <Content Include="TestData\PermissionEx\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
40 <Content Include="TestData\PermissionEx\Package.wxs" CopyToOutputDirectory="PreserveNewest" />
41 <Content Include="TestData\PermissionEx\PackageComponents.wxs" CopyToOutputDirectory="PreserveNewest" />
42 <Content Include="TestData\EventManifest\example.txt" CopyToOutputDirectory="PreserveNewest" />
43 <Content Include="TestData\EventManifest\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
44 <Content Include="TestData\EventManifest\Package.wxs" CopyToOutputDirectory="PreserveNewest" />
45 <Content Include="TestData\EventManifest\PackageComponents.wxs" CopyToOutputDirectory="PreserveNewest" />
46 <Content Include="TestData\Queries\example.txt" CopyToOutputDirectory="PreserveNewest" />
47 <Content Include="TestData\Queries\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
48 <Content Include="TestData\Queries\Package.wxs" CopyToOutputDirectory="PreserveNewest" />
49 <Content Include="TestData\Queries\PackageComponents.wxs" CopyToOutputDirectory="PreserveNewest" />
50 </ItemGroup> 16 </ItemGroup>
51 17
52 <ItemGroup> 18 <ItemGroup>
diff --git a/src/wixext/Symbols/XmlConfigSymbol.cs b/src/wixext/Symbols/XmlConfigSymbol.cs
index ca1cf047..6503a586 100644
--- a/src/wixext/Symbols/XmlConfigSymbol.cs
+++ b/src/wixext/Symbols/XmlConfigSymbol.cs
@@ -12,6 +12,7 @@ namespace WixToolset.Util
12 new[] 12 new[]
13 { 13 {
14 new IntermediateFieldDefinition(nameof(XmlConfigSymbolFields.File), IntermediateFieldType.String), 14 new IntermediateFieldDefinition(nameof(XmlConfigSymbolFields.File), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(XmlConfigSymbolFields.ElementId), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(XmlConfigSymbolFields.ElementPath), IntermediateFieldType.String), 16 new IntermediateFieldDefinition(nameof(XmlConfigSymbolFields.ElementPath), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(XmlConfigSymbolFields.VerifyPath), IntermediateFieldType.String), 17 new IntermediateFieldDefinition(nameof(XmlConfigSymbolFields.VerifyPath), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(XmlConfigSymbolFields.Name), IntermediateFieldType.String), 18 new IntermediateFieldDefinition(nameof(XmlConfigSymbolFields.Name), IntermediateFieldType.String),
@@ -31,6 +32,7 @@ namespace WixToolset.Util.Symbols
31 public enum XmlConfigSymbolFields 32 public enum XmlConfigSymbolFields
32 { 33 {
33 File, 34 File,
35 ElementId,
34 ElementPath, 36 ElementPath,
35 VerifyPath, 37 VerifyPath,
36 Name, 38 Name,
@@ -58,6 +60,12 @@ namespace WixToolset.Util.Symbols
58 set => this.Set((int)XmlConfigSymbolFields.File, value); 60 set => this.Set((int)XmlConfigSymbolFields.File, value);
59 } 61 }
60 62
63 public string ElementId
64 {
65 get => this.Fields[(int)XmlConfigSymbolFields.ElementId].AsString();
66 set => this.Set((int)XmlConfigSymbolFields.ElementId, value);
67 }
68
61 public string ElementPath 69 public string ElementPath
62 { 70 {
63 get => this.Fields[(int)XmlConfigSymbolFields.ElementPath].AsString(); 71 get => this.Fields[(int)XmlConfigSymbolFields.ElementPath].AsString();
diff --git a/src/wixext/UtilCompiler.cs b/src/wixext/UtilCompiler.cs
index 68c7a234..7314570e 100644
--- a/src/wixext/UtilCompiler.cs
+++ b/src/wixext/UtilCompiler.cs
@@ -3706,13 +3706,15 @@ namespace WixToolset.Util
3706 var symbol = section.AddSymbol(new XmlConfigSymbol(sourceLineNumbers, id) 3706 var symbol = section.AddSymbol(new XmlConfigSymbol(sourceLineNumbers, id)
3707 { 3707 {
3708 File = file, 3708 File = file,
3709 ElementPath = elementId ?? elementPath, 3709 ElementId = elementId,
3710 ElementPath = elementPath,
3710 VerifyPath = verifyPath, 3711 VerifyPath = verifyPath,
3711 Name = name, 3712 Name = name,
3712 Value = value, 3713 Value = value,
3713 Flags = flags, 3714 Flags = flags,
3714 ComponentRef = componentId, 3715 ComponentRef = componentId,
3715 }); 3716 });
3717
3716 if (CompilerConstants.IntegerNotSet != sequence) 3718 if (CompilerConstants.IntegerNotSet != sequence)
3717 { 3719 {
3718 symbol.Sequence = sequence; 3720 symbol.Sequence = sequence;
diff --git a/src/wixext/UtilTableDefinitions.cs b/src/wixext/UtilTableDefinitions.cs
index e5d0850f..1908915c 100644
--- a/src/wixext/UtilTableDefinitions.cs
+++ b/src/wixext/UtilTableDefinitions.cs
@@ -253,7 +253,8 @@ namespace WixToolset.Util
253 { 253 {
254 new ColumnDefinition("Wix4XmlConfig", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token.", modularizeType: ColumnModularizeType.Column), 254 new ColumnDefinition("Wix4XmlConfig", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token.", modularizeType: ColumnModularizeType.Column),
255 new ColumnDefinition("File", ColumnType.Localized, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "The .XML file in which to write the information", modularizeType: ColumnModularizeType.Property), 255 new ColumnDefinition("File", ColumnType.Localized, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "The .XML file in which to write the information", modularizeType: ColumnModularizeType.Property),
256 new ColumnDefinition("ElementPath", ColumnType.Localized, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "The XPATH query for an element to modify or add children to. Can also be a foreign key reference to another Wix4XmlConfig row if no attributes are set and the row referenced is a create element row.", modularizeType: ColumnModularizeType.Property), 256 new ColumnDefinition("ElementId", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Wix4XmlConfig", keyColumn: 1, description: "A foreign key reference to another Wix4XmlConfig row if no attributes are set and the row referenced is a create element row.", modularizeType: ColumnModularizeType.Column),
257 new ColumnDefinition("ElementPath", ColumnType.Localized, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "The XPATH query for an element to modify or add children to. Must be null if ElementId is provided", modularizeType: ColumnModularizeType.Property),
257 new ColumnDefinition("VerifyPath", ColumnType.Localized, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "The XPATH query run from ElementPath to verify whether a repair is necessary. Also used to uninstall.", modularizeType: ColumnModularizeType.Property), 258 new ColumnDefinition("VerifyPath", ColumnType.Localized, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "The XPATH query run from ElementPath to verify whether a repair is necessary. Also used to uninstall.", modularizeType: ColumnModularizeType.Property),
258 new ColumnDefinition("Name", ColumnType.Localized, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "The .XML file node to set/add in the element.", modularizeType: ColumnModularizeType.Property), 259 new ColumnDefinition("Name", ColumnType.Localized, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "The .XML file node to set/add in the element.", modularizeType: ColumnModularizeType.Property),
259 new ColumnDefinition("Value", ColumnType.Localized, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "The value to be written.", modularizeType: ColumnModularizeType.Property), 260 new ColumnDefinition("Value", ColumnType.Localized, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "The value to be written.", modularizeType: ColumnModularizeType.Property),