@joebigelow / wix / commits / ab8d368f

Fix XmlConfig lookup logic.

Fixes https://github.com/wixtoolset/issues/issues/7377. Requires fix for https://github.com/wixtoolset/issues/issues/7444.

Bob Arnson committed Apr 27, 2023 at 21:06 UTC ab8d368fe8e7a41e503ec295b196035922293ef4
8 files changed +134 -16
src/ext/Util/ca/XmlConfig.cpp
+4 -9
@@ -266,11 +266,11 @@ static HRESULT ProcessChanges(
266 // Keep track of where our next spot will be since our current node may be moved
267 pxfcNext = pxfc->pxfcNext;
268
269 - // With each node, check to see if it's element path matches the Id of some other node in the list
269 + // With each node, check to see if its element path matches the Id of some other node in the list
270 pxfcCheck = *ppxfcHead;
271 while (pxfcCheck)
272 {
273 - if (pxfc->pwzElementId)
273 + if (pxfc->pwzElementId && *pxfc->pwzElementId)
274 {
275 if (0 == lstrcmpW(pxfc->pwzElementId, pxfcCheck->wzId)
276 && 0 == pxfc->iXmlFlags
@@ -315,11 +315,6 @@ static HRESULT ProcessChanges(
315 pxfcCheck->cAdditionalChanges = ++cAdditionalChanges;
316 }
317 }
318 - else
319 - {
320 - hr = E_NOTFOUND;
321 - ExitOnRootFailure(hr, "failed to find matching ElementId: %ls", pxfc->pwzElementId);
322 - }
318 }
319
320 pxfcCheck = pxfcCheck->pxfcNext;
@@ -402,10 +397,10 @@ static HRESULT WriteChangeData(
397
398 HRESULT hr = S_OK;
399 XML_CONFIG_CHANGE* pxfcAdditionalChanges = NULL;
405 - LPCWSTR wzElementPath = pxfc->pwzElementId ? pxfc->pwzElementId : pxfc->pwzElementPath;
400 + LPCWSTR wzElementPath = pxfc->pwzElementId && *pxfc->pwzElementId ? pxfc->pwzElementId : pxfc->pwzElementPath;
401
402 hr = WcaWriteStringToCaData(wzElementPath, ppwzCustomActionData);
408 - ExitOnFailure(hr, "failed to write ElementPath to custom action data: %ls", wzElementPath);
403 + ExitOnFailure(hr, "failed to write ElementId/ElementPath to custom action data: %ls", wzElementPath);
404
405 hr = WcaWriteStringToCaData(pxfc->pwzVerifyPath, ppwzCustomActionData);
406 ExitOnFailure(hr, "failed to write VerifyPath to custom action data: %ls", pxfc->pwzVerifyPath);
src/ext/Util/test/WixToolsetTest.Util/TestData/XmlConfig/Package.wxs
+16 -6
@@ -1,17 +1,27 @@
1 -<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
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 Directory="INSTALLFOLDER">
7 + <File Id="MyXmlFile" Source="my.xml" />
8 + </Component>
9 +
10 <Component Id="Del" Directory="INSTALLFOLDER" Guid="3613414c-11f5-40fa-a1f1-a0ba722a6895">
7 - <util:XmlConfig Id="DelElement" File="[INSTALLFOLDER]my.xml" Action="delete" Node="element" VerifyPath="xxx" ElementPath="//root/sub" On="install" Sequence="1" />
11 + <util:XmlConfig Id="DelElement" File="[#MyXmlFile]" Action="delete" Node="element" VerifyPath="grandchild1" ElementPath="//root/child1" On="install" />
12 + </Component>
13 +
14 + <Component Id="Add" Directory="INSTALLFOLDER" Guid="30A9FF8B-7AC8-47F3-BB24-9EA81AA38856">
15 + <util:XmlConfig Id="AddElement" File="[#MyXmlFile]" Action="create" Node="element" ElementPath="//root/child2" Name="grandchild3" On="install" Sequence="2" />
16 + <util:XmlConfig ElementId="AddElement" File="[#MyXmlFile]" Name="TheAttribute1" Value="AttributeValue1" Sequence="3" />
17 + <util:XmlConfig Id="AddAttribute2" ElementId="AddElement" File="[INSTALLFOLDER]my.xml" Name="TheAttribute2" Value="AttributeValue2" Sequence="4" />
18 </Component>
19 </Feature>
20 </Package>
21
22 <Fragment>
13 - <StandardDirectory Id="ProgramFilesFolder">
14 - <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
15 - </StandardDirectory>
16 - </Fragment>
23 + <StandardDirectory Id="ProgramFilesFolder">
24 + <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
25 + </StandardDirectory>
26 + </Fragment>
27 </Wix>
src/ext/Util/test/WixToolsetTest.Util/TestData/XmlConfig/my.xml new
+11
@@ -0,0 +1,11 @@
1 +<root>
2 + <child1>
3 + <grandchild1>
4 + </grandchild1>
5 + </child1>
6 +
7 + <child2>
8 + <grandchild2>
9 + </grandchild2>
10 + </child2>
11 +</root>
src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs
+5 -1
@@ -10,6 +10,7 @@ namespace WixToolsetTest.Util
10 using WixToolset.Util;
11 using Xunit;
12 using System.Xml.Linq;
13 + using System;
14
15 public class UtilExtensionFixture
16 {
@@ -293,7 +294,10 @@ namespace WixToolsetTest.Util
294 var results = build.BuildAndQuery(BuildX64, "Wix4XmlConfig");
295 WixAssert.CompareLineByLine(new[]
296 {
296 - "Wix4XmlConfig:DelElement\t[INSTALLFOLDER]my.xml\t\t//root/sub\txxx\t\t\t289\tDel\t1",
297 + "Wix4XmlConfig:AddAttribute2\t[INSTALLFOLDER]my.xml\tAddElement\t\t\tTheAttribute2\tAttributeValue2\t0\tAdd\t4",
298 + "Wix4XmlConfig:AddElement\t[#MyXmlFile]\t\t//root/child2\t\tgrandchild3\t\t273\tAdd\t2",
299 + "Wix4XmlConfig:DelElement\t[#MyXmlFile]\t\t//root/child1\tgrandchild1\t\t\t289\tDel\t",
300 + "Wix4XmlConfig:uxcPPF6g4HJEQpBLT9w9GT6SKyHWww\t[#MyXmlFile]\tAddElement\t\t\tTheAttribute1\tAttributeValue1\t0\tAdd\t3",
301 }, results.OrderBy(s => s).ToArray());
302 }
303
src/test/msi/TestData/XmlConfigTests/XmlConfig/Package.wxs new
+27
@@ -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="XmlConfig" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
3 + <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
4 +
5 + <Feature Id="ProductFeature" Title="XmlConfig">
6 + <Component Directory="INSTALLFOLDER">
7 + <File Id="MyXmlFile" Source="my.xml" />
8 + </Component>
9 +
10 + <Component Id="Del" Directory="INSTALLFOLDER" Guid="3613414c-11f5-40fa-a1f1-a0ba722a6895">
11 + <util:XmlConfig Id="DelElement" File="[#MyXmlFile]" Action="delete" Node="element" VerifyPath="grandchild1" ElementPath="//root/child1" On="install" />
12 + </Component>
13 +
14 + <Component Id="Add" Directory="INSTALLFOLDER" Guid="30A9FF8B-7AC8-47F3-BB24-9EA81AA38856">
15 + <util:XmlConfig Id="AddElement" File="[#MyXmlFile]" Action="create" Node="element" ElementPath="//root/child2" Name="grandchild3" On="install" Sequence="2" />
16 + <util:XmlConfig ElementId="AddElement" File="[#MyXmlFile]" Name="TheAttribute1" Value="AttributeValue1" Sequence="3" />
17 + <util:XmlConfig Id="AddAttribute2" ElementId="AddElement" File="[INSTALLFOLDER]my.xml" Name="TheAttribute2" Value="AttributeValue2" Sequence="4" />
18 + </Component>
19 + </Feature>
20 + </Package>
21 +
22 + <Fragment>
23 + <StandardDirectory Id="ProgramFilesFolder">
24 + <Directory Id="INSTALLFOLDER" Name="XmlConfig" />
25 + </StandardDirectory>
26 + </Fragment>
27 +</Wix>
src/test/msi/TestData/XmlConfigTests/XmlConfig/XmlConfig.wixproj new
+6
@@ -0,0 +1,6 @@
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 +<Project Sdk="WixToolset.Sdk">
3 + <ItemGroup>
4 + <PackageReference Include="WixToolset.Util.wixext" />
5 + </ItemGroup>
6 +</Project>
\ No newline at end of file
src/test/msi/TestData/XmlConfigTests/XmlConfig/my.xml new
+11
@@ -0,0 +1,11 @@
1 +<root>
2 + <child1>
3 + <grandchild1>
4 + </grandchild1>
5 + </child1>
6 +
7 + <child2>
8 + <grandchild2>
9 + </grandchild2>
10 + </child2>
11 +</root>
src/test/msi/WixToolsetTest.MsiE2E/XmlConfigTests.cs new
+54
@@ -0,0 +1,54 @@
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.MsiE2E;
4 +
5 +using System;
6 +using System.IO;
7 +using System.Xml.Linq;
8 +using WixTestTools;
9 +using Xunit;
10 +using Xunit.Abstractions;
11 +
12 +public class XmlConfigTests : MsiE2ETests
13 +{
14 + public XmlConfigTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
15 + {
16 + }
17 +
18 + [RuntimeFact]
19 + public void CanModifyXmlFileWithXmlConfig()
20 + {
21 + var product = this.CreatePackageInstaller("XmlConfig");
22 +
23 + product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS);
24 +
25 + // Validate the expected changes in my.xml.
26 + var myXmlPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "XmlConfig", "my.xml");
27 + var content = File.ReadAllText(myXmlPath);
28 + var xDoc = XDocument.Parse(content);
29 +
30 + var xRoot = xDoc.Element("root");
31 + var xChild1 = xRoot.Element("child1");
32 + Assert.NotNull(xChild1);
33 +
34 + var xGrandchild1 = xChild1.Element("grandchild1");
35 + Assert.Null(xGrandchild1);
36 +
37 + var xChild2 = xRoot.Element("child2");
38 + Assert.NotNull(xChild2);
39 +
40 + var xGrandchild3 = xChild2.Element("grandchild3");
41 + Assert.NotNull(xGrandchild3);
42 + Assert.True(xGrandchild3.HasAttributes);
43 +
44 + var xAttribute1 = xGrandchild3.Attribute("TheAttribute1");
45 + Assert.NotNull(xAttribute1);
46 + Assert.Equal("AttributeValue1", xAttribute1.Value);
47 +
48 + var xAttribute2 = xGrandchild3.Attribute("TheAttribute2");
49 + Assert.NotNull(xAttribute2);
50 + Assert.Equal("AttributeValue2", xAttribute2.Value);
51 +
52 + product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS);
53 + }
54 +}