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
}