@joebigelow / wix-1 / commits / 05cafee8

Add conversion for BootstrapperApplicationDll and bal:UseUILanguages.

Sean Hall committed Dec 8, 2020 at 15:14 UTC 05cafee83e597badaf842bd7e6ba06f4d8fe193f
4 files changed +237 -8
src/WixToolset.Converters.Symbolizer/WixToolset.Converters.Symbolizer.csproj
+1 -1
@@ -30,6 +30,6 @@
30
31 <ItemGroup>
32 <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
33 - <PackageReference Include="Nerdbank.GitVersioning" Version="3.1.91" PrivateAssets="All" />
33 + <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" PrivateAssets="All" />
34 </ItemGroup>
35 </Project>
src/WixToolset.Converters/WixConverter.cs
+94 -3
@@ -31,6 +31,7 @@ namespace WixToolset.Converters
31 private const char XDocumentNewLine = '\n'; // XDocument normalizes "\r\n" to just "\n".
32 private static readonly XNamespace WixNamespace = "http://wixtoolset.org/schemas/v4/wxs";
33 private static readonly XNamespace Wix3Namespace = "http://schemas.microsoft.com/wix/2006/wi";
34 + private static readonly XNamespace WixBalNamespace = "http://wixtoolset.org/schemas/v4/wxs/bal";
35 private static readonly XNamespace WixUtilNamespace = "http://wixtoolset.org/schemas/v4/wxs/util";
36 private static readonly XNamespace WixFirewallNamespace = "http://wixtoolset.org/schemas/v4/wxs/firewall";
37
@@ -40,6 +41,7 @@ namespace WixToolset.Converters
41 private static readonly XName InstallExecuteSequenceElementName = WixNamespace + "InstallExecuteSequence";
42 private static readonly XName InstallUISequenceSequenceElementName = WixNamespace + "InstallUISequence";
43 private static readonly XName BootstrapperApplicationElementName = WixNamespace + "BootstrapperApplication";
44 + private static readonly XName BootstrapperApplicationDllElementName = WixNamespace + "BootstrapperApplicationDll";
45 private static readonly XName EmbeddedChainerElementName = WixNamespace + "EmbeddedChainer";
46 private static readonly XName ColumnElementName = WixNamespace + "Column";
47 private static readonly XName ComponentElementName = WixNamespace + "Component";
@@ -77,6 +79,7 @@ namespace WixToolset.Converters
79 private static readonly XName UITextElementName = WixNamespace + "UIText";
80 private static readonly XName VariableElementName = WixNamespace + "Variable";
81 private static readonly XName VerbElementName = WixNamespace + "Verb";
82 + private static readonly XName BalUseUILanguagesName = WixBalNamespace + "UseUILanguages";
83 private static readonly XName UtilCloseApplicationElementName = WixUtilNamespace + "CloseApplication";
84 private static readonly XName UtilPermissionExElementName = WixUtilNamespace + "PermissionEx";
85 private static readonly XName UtilRegistrySearchName = WixUtilNamespace + "RegistrySearch";
@@ -453,10 +456,83 @@ namespace WixToolset.Converters
456
457 private void ConvertBootstrapperApplicationElement(XElement element)
458 {
456 - if (this.SourceVersion < 4 && null == element.Attribute("DpiAwareness") &&
457 - this.OnError(ConverterTestType.AssignBootstrapperApplicationDpiAwareness, element, "The BootstrapperApplication DpiAwareness attribute is being set to 'unaware' to ensure it remains the same as the v3 default"))
459 + var xUseUILanguages = element.Attribute(BalUseUILanguagesName);
460 + if (xUseUILanguages != null &&
461 + this.OnError(ConverterTestType.BalUseUILanguagesDeprecated, element, "bal:UseUILanguages is deprecated, 'true' is now the standard behavior."))
462 {
459 - element.Add(new XAttribute("DpiAwareness", "unaware"));
463 + xUseUILanguages.Remove();
464 + }
465 +
466 + var xBADll = element.Elements(BootstrapperApplicationDllElementName).FirstOrDefault();
467 + if (xBADll == null)
468 + {
469 + xBADll = this.CreateBootstrapperApplicationDllElement(element);
470 +
471 + if (xBADll != null)
472 + {
473 + element.Add(Environment.NewLine);
474 + element.Add(xBADll);
475 + element.Add(Environment.NewLine);
476 + }
477 + }
478 + }
479 +
480 + private XElement CreateBootstrapperApplicationDllElement(XElement element)
481 + {
482 + XElement xBADll = null;
483 + var xSource = element.Attribute("SourceFile");
484 + var xDpiAwareness = element.Attribute("DpiAwareness");
485 +
486 + if (xSource != null)
487 + {
488 + if (xBADll != null || CreateBADllElement(element, out xBADll))
489 + {
490 + MoveAttribute(element, "SourceFile", xBADll);
491 + MoveAttribute(element, "Name", xBADll);
492 + }
493 + }
494 + else if (xDpiAwareness != null || this.SourceVersion < 4) // older code might be relying on old behavior of first Payload element being the BA dll.
495 + {
496 + var xFirstChild = element.Elements().FirstOrDefault();
497 + if (xFirstChild?.Name == PayloadElementName)
498 + {
499 + if (xBADll != null || CreateBADllElement(element, out xBADll))
500 + {
501 + var attributes = xFirstChild.Attributes().ToList();
502 + xFirstChild.Remove();
503 +
504 + foreach (var attribute in attributes)
505 + {
506 + xBADll.Add(attribute);
507 + }
508 + }
509 + }
510 + else
511 + {
512 + this.OnError(ConverterTestType.BootstrapperApplicationDllRequired, element, "The new BootstrapperApplicationDll element is required but could not be added automatically since the bootstrapper application dll was not directly specified.");
513 + }
514 + }
515 +
516 + if (xDpiAwareness != null)
517 + {
518 + if (xBADll != null || CreateBADllElement(element, out xBADll))
519 + {
520 + MoveAttribute(element, "DpiAwareness", xBADll);
521 + }
522 + }
523 + else if (this.SourceVersion < 4 && xBADll != null &&
524 + this.OnError(ConverterTestType.AssignBootstrapperApplicationDpiAwareness, element, "The BootstrapperApplicationDll DpiAwareness attribute is being set to 'unaware' to ensure it remains the same as the v3 default"))
525 + {
526 + xBADll.Add(new XAttribute("DpiAwareness", "unaware"));
527 + }
528 +
529 + return xBADll;
530 +
531 + bool CreateBADllElement(XObject node, out XElement xCreatedBADll)
532 + {
533 + var create = this.OnError(ConverterTestType.BootstrapperApplicationDll, node, "The bootstrapper application dll is now specified in the BootstrapperApplicationDll element.");
534 + xCreatedBADll = create ? new XElement(BootstrapperApplicationDllElementName) : null;
535 + return create;
536 }
537 }
538
@@ -1489,6 +1565,21 @@ namespace WixToolset.Converters
1565 /// Verb/@Target can't be converted.
1566 /// </summary>
1567 VerbTargetNotConvertable,
1568 +
1569 + /// <summary>
1570 + /// The bootstrapper application dll is now specified in its own element.
1571 + /// </summary>
1572 + BootstrapperApplicationDll,
1573 +
1574 + /// <summary>
1575 + /// The new bootstrapper application dll element is required.
1576 + /// </summary>
1577 + BootstrapperApplicationDllRequired,
1578 +
1579 + /// <summary>
1580 + /// bal:UseUILanguages is deprecated, 'true' is now the standard behavior.
1581 + /// </summary>
1582 + BalUseUILanguagesDeprecated,
1583 }
1584 }
1585 }
src/WixToolset.Converters/WixToolset.Converters.csproj
+1 -1
@@ -22,6 +22,6 @@
22
23 <ItemGroup>
24 <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
25 - <PackageReference Include="Nerdbank.GitVersioning" Version="3.1.91" PrivateAssets="All" />
25 + <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" PrivateAssets="All" />
26 </ItemGroup>
27 </Project>
src/test/WixToolsetTest.Converters/BootstrapperApplicationFixture.cs
+141 -3
@@ -12,12 +12,14 @@ namespace WixToolsetTest.Converters
12 public class BootstrapperApplicationFixture : BaseConverterFixture
13 {
14 [Fact]
15 - public void SetsDpiUnawareFromV3()
15 + public void CantCreateBootstrapperApplicationDllFromV3PayloadGroupRef()
16 {
17 var parse = String.Join(Environment.NewLine,
18 "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>",
19 " <Fragment>",
20 - " <BootstrapperApplication Id='ba' />",
20 + " <BootstrapperApplication Id='ba'>",
21 + " <PayloadGroupRef Id='baPayloads' />",
22 + " </BootstrapperApplication>",
23 " </Fragment>",
24 "</Wix>");
25
@@ -25,7 +27,9 @@ namespace WixToolsetTest.Converters
27 {
28 "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
29 " <Fragment>",
28 - " <BootstrapperApplication Id=\"ba\" DpiAwareness=\"unaware\" />",
30 + " <BootstrapperApplication Id=\"ba\">",
31 + " <PayloadGroupRef Id=\"baPayloads\" />",
32 + " </BootstrapperApplication>",
33 " </Fragment>",
34 "</Wix>"
35 };
@@ -42,6 +46,76 @@ namespace WixToolsetTest.Converters
46 WixAssert.CompareLineByLine(expected, actualLines);
47 }
48
49 + [Fact]
50 + public void CreateBootstrapperApplicationDllFromV3()
51 + {
52 + var parse = String.Join(Environment.NewLine,
53 + "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>",
54 + " <Fragment>",
55 + " <BootstrapperApplication Id='ba' SourceFile='ba.dll' />",
56 + " </Fragment>",
57 + "</Wix>");
58 +
59 + var expected = new[]
60 + {
61 + "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
62 + " <Fragment>",
63 + " <BootstrapperApplication Id=\"ba\">",
64 + "<BootstrapperApplicationDll SourceFile=\"ba.dll\" DpiAwareness=\"unaware\" />",
65 + "</BootstrapperApplication>",
66 + " </Fragment>",
67 + "</Wix>"
68 + };
69 +
70 + var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
71 +
72 + var messaging = new MockMessaging();
73 + var converter = new WixConverter(messaging, 2, null, null);
74 +
75 + var errors = converter.ConvertDocument(document);
76 + Assert.Equal(3, errors);
77 +
78 + var actualLines = UnformattedDocumentLines(document);
79 + WixAssert.CompareLineByLine(expected, actualLines);
80 + }
81 +
82 + [Fact]
83 + public void CreateBootstrapperApplicationDllFromV3Payload()
84 + {
85 + var parse = String.Join(Environment.NewLine,
86 + "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>",
87 + " <Fragment>",
88 + " <BootstrapperApplication Id='ba'>",
89 + " <Payload SourceFile='ba.dll' />",
90 + " </BootstrapperApplication>",
91 + " </Fragment>",
92 + "</Wix>");
93 +
94 + var expected = new[]
95 + {
96 + "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
97 + " <Fragment>",
98 + " <BootstrapperApplication Id=\"ba\">",
99 + " ",
100 + " ",
101 + "<BootstrapperApplicationDll SourceFile=\"ba.dll\" DpiAwareness=\"unaware\" />",
102 + "</BootstrapperApplication>",
103 + " </Fragment>",
104 + "</Wix>"
105 + };
106 +
107 + var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
108 +
109 + var messaging = new MockMessaging();
110 + var converter = new WixConverter(messaging, 2, null, null);
111 +
112 + var errors = converter.ConvertDocument(document);
113 + Assert.Equal(3, errors);
114 +
115 + var actualLines = UnformattedDocumentLines(document);
116 + WixAssert.CompareLineByLine(expected, actualLines);
117 + }
118 +
119 [Fact]
120 public void DoesntSetDpiUnawareFromV4()
121 {
@@ -72,5 +146,69 @@ namespace WixToolsetTest.Converters
146 var actualLines = UnformattedDocumentLines(document);
147 WixAssert.CompareLineByLine(expected, actualLines);
148 }
149 +
150 + [Fact]
151 + public void KeepsDpiAwarenessFromV4()
152 + {
153 + var parse = String.Join(Environment.NewLine,
154 + "<Wix xmlns='http://wixtoolset.org/schemas/v4/wxs'>",
155 + " <Fragment>",
156 + " <BootstrapperApplication Id='ba' SourceFile='ba.dll' DpiAwareness='system' />",
157 + " </Fragment>",
158 + "</Wix>");
159 +
160 + var expected = new[]
161 + {
162 + "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
163 + " <Fragment>",
164 + " <BootstrapperApplication Id=\"ba\">",
165 + "<BootstrapperApplicationDll SourceFile=\"ba.dll\" DpiAwareness=\"system\" />",
166 + "</BootstrapperApplication>",
167 + " </Fragment>",
168 + "</Wix>"
169 + };
170 +
171 + var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
172 +
173 + var messaging = new MockMessaging();
174 + var converter = new WixConverter(messaging, 2, null, null);
175 +
176 + var errors = converter.ConvertDocument(document);
177 + Assert.Equal(1, errors);
178 +
179 + var actualLines = UnformattedDocumentLines(document);
180 + WixAssert.CompareLineByLine(expected, actualLines);
181 + }
182 +
183 + [Fact]
184 + public void RemovesBalUseUILanguages()
185 + {
186 + var parse = String.Join(Environment.NewLine,
187 + "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi' xmlns:bal='http://schemas.microsoft.com/wix/BalExtension'>",
188 + " <Fragment>",
189 + " <BootstrapperApplication Id='ba' bal:UseUILanguages='true' />",
190 + " </Fragment>",
191 + "</Wix>");
192 +
193 + var expected = new[]
194 + {
195 + "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\" xmlns:bal=\"http://wixtoolset.org/schemas/v4/wxs/bal\">",
196 + " <Fragment>",
197 + " <BootstrapperApplication Id=\"ba\" />",
198 + " </Fragment>",
199 + "</Wix>"
200 + };
201 +
202 + var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
203 +
204 + var messaging = new MockMessaging();
205 + var converter = new WixConverter(messaging, 2, null, null);
206 +
207 + var errors = converter.ConvertDocument(document);
208 + Assert.Equal(4, errors);
209 +
210 + var actualLines = UnformattedDocumentLines(document);
211 + WixAssert.CompareLineByLine(expected, actualLines);
212 + }
213 }
214 }