Add conversion for built-in BA usage from BootstrapperApplicationRef.
Sean Hall committed
Dec 8, 2020 at 21:35 UTC
7378de4301d4f8c2570b29268ca7affbdb5721c2
2 files changed
+314
src/WixToolset.Converters/WixConverter.cs
+110
@@ -42,6 +42,7 @@ namespace WixToolset.Converters
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 BootstrapperApplicationRefElementName = WixNamespace + "BootstrapperApplicationRef";
46
private static readonly XName EmbeddedChainerElementName = WixNamespace + "EmbeddedChainer";
47
private static readonly XName ColumnElementName = WixNamespace + "Column";
48
private static readonly XName ComponentElementName = WixNamespace + "Component";
@@ -80,6 +81,10 @@ namespace WixToolset.Converters
81
private static readonly XName VariableElementName = WixNamespace + "Variable";
82
private static readonly XName VerbElementName = WixNamespace + "Verb";
83
private static readonly XName BalUseUILanguagesName = WixBalNamespace + "UseUILanguages";
84
+ private static readonly XName BalStandardBootstrapperApplicationName = WixBalNamespace + "WixStandardBootstrapperApplication";
85
+ private static readonly XName BalManagedBootstrapperApplicationHostName = WixBalNamespace + "WixManagedBootstrapperApplicationHost";
86
+ private static readonly XName BalOldDotNetCoreBootstrapperApplicationName = WixBalNamespace + "WixDotNetCoreBootstrapperApplication";
87
+ private static readonly XName BalNewDotNetCoreBootstrapperApplicationName = WixBalNamespace + "WixDotNetCoreBootstrapperApplicationHost";
88
private static readonly XName UtilCloseApplicationElementName = WixUtilNamespace + "CloseApplication";
89
private static readonly XName UtilPermissionExElementName = WixUtilNamespace + "PermissionEx";
90
private static readonly XName UtilRegistrySearchName = WixUtilNamespace + "RegistrySearch";
@@ -142,6 +147,7 @@ namespace WixToolset.Converters
147
{ WixConverter.InstallUISequenceSequenceElementName, this.ConvertSequenceElement },
148
{ WixConverter.InstallExecuteSequenceElementName, this.ConvertSequenceElement },
149
{ WixConverter.BootstrapperApplicationElementName, this.ConvertBootstrapperApplicationElement },
150
+ { WixConverter.BootstrapperApplicationRefElementName, this.ConvertBootstrapperApplicationRefElement },
151
{ WixConverter.ColumnElementName, this.ConvertColumnElement },
152
{ WixConverter.CustomTableElementName, this.ConvertCustomTableElement },
153
{ WixConverter.ControlElementName, this.ConvertControlElement },
@@ -536,6 +542,105 @@ namespace WixToolset.Converters
542
}
543
}
544
545
+ private void ConvertBootstrapperApplicationRefElement(XElement element)
546
+ {
547
+ var xUseUILanguages = element.Attribute(BalUseUILanguagesName);
548
+ if (xUseUILanguages != null &&
549
+ this.OnError(ConverterTestType.BalUseUILanguagesDeprecated, element, "bal:UseUILanguages is deprecated, 'true' is now the standard behavior."))
550
+ {
551
+ xUseUILanguages.Remove();
552
+ }
553
+
554
+ var xId = element.Attribute("Id");
555
+ if (xId != null)
556
+ {
557
+ XName balBAName = null;
558
+ XName oldBalBAName = null;
559
+ string theme = null;
560
+
561
+ switch (xId.Value)
562
+ {
563
+ case "WixStandardBootstrapperApplication.RtfLicense":
564
+ balBAName = BalStandardBootstrapperApplicationName;
565
+ theme = "rtfLicense";
566
+ break;
567
+ case "WixStandardBootstrapperApplication.RtfLargeLicense":
568
+ balBAName = BalStandardBootstrapperApplicationName;
569
+ theme = "rtfLargeLicense";
570
+ break;
571
+ case "WixStandardBootstrapperApplication.HyperlinkLicense":
572
+ balBAName = BalStandardBootstrapperApplicationName;
573
+ theme = "hyperlinkLicense";
574
+ break;
575
+ case "WixStandardBootstrapperApplication.HyperlinkLargeLicense":
576
+ balBAName = BalStandardBootstrapperApplicationName;
577
+ theme = "hyperlinkLargeLicense";
578
+ break;
579
+ case "WixStandardBootstrapperApplication.HyperlinkSidebarLicense":
580
+ balBAName = BalStandardBootstrapperApplicationName;
581
+ theme = "hyperlinkSidebarLicense";
582
+ break;
583
+ case "WixStandardBootstrapperApplication.Foundation":
584
+ balBAName = BalStandardBootstrapperApplicationName;
585
+ theme = "none";
586
+ break;
587
+ case "ManagedBootstrapperApplicationHost":
588
+ case "ManagedBootstrapperApplicationHost.RtfLicense":
589
+ balBAName = BalManagedBootstrapperApplicationHostName;
590
+ theme = "standard";
591
+ break;
592
+ case "ManagedBootstrapperApplicationHost.Minimal":
593
+ case "ManagedBootstrapperApplicationHost.RtfLicense.Minimal":
594
+ case "ManagedBootstrapperApplicationHost.Foundation":
595
+ balBAName = BalManagedBootstrapperApplicationHostName;
596
+ theme = "none";
597
+ break;
598
+ case "DotNetCoreBootstrapperApplicationHost":
599
+ case "DotNetCoreBootstrapperApplicationHost.RtfLicense":
600
+ balBAName = BalNewDotNetCoreBootstrapperApplicationName;
601
+ oldBalBAName = BalOldDotNetCoreBootstrapperApplicationName;
602
+ theme = "standard";
603
+ break;
604
+ case "DotNetCoreBootstrapperApplicationHost.Minimal":
605
+ case "DotNetCoreBootstrapperApplicationHost.RtfLicense.Minimal":
606
+ case "DotNetCoreBootstrapperApplicationHost.Foundation":
607
+ balBAName = BalNewDotNetCoreBootstrapperApplicationName;
608
+ oldBalBAName = BalOldDotNetCoreBootstrapperApplicationName;
609
+ theme = "none";
610
+ break;
611
+ }
612
+
613
+ if (balBAName != null && theme != null &&
614
+ this.OnError(ConverterTestType.BalBootstrapperApplicationRefToElement, element, "Built-in bootstrapper applications must be referenced through their custom element"))
615
+ {
616
+ element.Name = BootstrapperApplicationElementName;
617
+ xId.Remove();
618
+ this.ConvertBalBootstrapperApplicationRef(element, theme, balBAName, oldBalBAName);
619
+ }
620
+ }
621
+ }
622
+
623
+ private void ConvertBalBootstrapperApplicationRef(XElement element, string theme, XName balBAElementName, XName oldBalBAElementName = null)
624
+ {
625
+ var xBalBa = element.Element(oldBalBAElementName ?? balBAElementName);
626
+ if (xBalBa == null)
627
+ {
628
+ xBalBa = new XElement(balBAElementName);
629
+ element.Add(Environment.NewLine);
630
+ element.Add(xBalBa);
631
+ element.Add(Environment.NewLine);
632
+ }
633
+ else if (oldBalBAElementName != null)
634
+ {
635
+ xBalBa.Name = BalNewDotNetCoreBootstrapperApplicationName;
636
+ }
637
+
638
+ if (theme != "standard")
639
+ {
640
+ xBalBa.Add(new XAttribute("Theme", theme));
641
+ }
642
+ }
643
+
644
private void ConvertColumnElement(XElement element)
645
{
646
var category = element.Attribute("Category");
@@ -1580,6 +1685,11 @@ namespace WixToolset.Converters
1685
/// bal:UseUILanguages is deprecated, 'true' is now the standard behavior.
1686
/// </summary>
1687
BalUseUILanguagesDeprecated,
1688
+
1689
+ /// <summary>
1690
+ /// The custom elements for built-in BAs are now required.
1691
+ /// </summary>
1692
+ BalBootstrapperApplicationRefToElement,
1693
}
1694
}
1695
}
src/test/WixToolsetTest.Converters/BootstrapperApplicationFixture.cs
+204
@@ -46,6 +46,210 @@ namespace WixToolsetTest.Converters
46
WixAssert.CompareLineByLine(expected, actualLines);
47
}
48
49
+ [Fact]
50
+ public void ConvertDotNetCoreBootstrapperApplicationRefWithExistingElement()
51
+ {
52
+ var parse = String.Join(Environment.NewLine,
53
+ "<Wix xmlns='http://wixtoolset.org/schemas/v4/wxs' xmlns:bal='http://wixtoolset.org/schemas/v4/wxs/bal'>",
54
+ " <Fragment>",
55
+ " <BootstrapperApplicationRef Id='DotNetCoreBootstrapperApplicationHost.Minimal'>",
56
+ " <bal:WixDotNetCoreBootstrapperApplication SelfContainedDeployment='yes' />",
57
+ " </BootstrapperApplicationRef>",
58
+ " </Fragment>",
59
+ "</Wix>");
60
+
61
+ var expected = new[]
62
+ {
63
+ "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\" xmlns:bal=\"http://wixtoolset.org/schemas/v4/wxs/bal\">",
64
+ " <Fragment>",
65
+ " <BootstrapperApplication>",
66
+ " <bal:WixDotNetCoreBootstrapperApplicationHost SelfContainedDeployment=\"yes\" Theme=\"none\" />",
67
+ " </BootstrapperApplication>",
68
+ " </Fragment>",
69
+ "</Wix>"
70
+ };
71
+
72
+ var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
73
+
74
+ var messaging = new MockMessaging();
75
+ var converter = new WixConverter(messaging, 2, null, null);
76
+
77
+ var errors = converter.ConvertDocument(document);
78
+ Assert.Equal(1, errors);
79
+
80
+ var actualLines = UnformattedDocumentLines(document);
81
+ WixAssert.CompareLineByLine(expected, actualLines);
82
+ }
83
+
84
+ [Fact]
85
+ public void ConvertDotNetCoreBootstrapperApplicationRefWithoutExistingElement()
86
+ {
87
+ var parse = String.Join(Environment.NewLine,
88
+ "<Wix xmlns='http://wixtoolset.org/schemas/v4/wxs' xmlns:bal='http://wixtoolset.org/schemas/v4/wxs/bal'>",
89
+ " <Fragment>",
90
+ " <BootstrapperApplicationRef Id='DotNetCoreBootstrapperApplicationHost' />",
91
+ " </Fragment>",
92
+ "</Wix>");
93
+
94
+ var expected = new[]
95
+ {
96
+ "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\" xmlns:bal=\"http://wixtoolset.org/schemas/v4/wxs/bal\">",
97
+ " <Fragment>",
98
+ " <BootstrapperApplication>",
99
+ "<bal:WixDotNetCoreBootstrapperApplicationHost />",
100
+ "</BootstrapperApplication>",
101
+ " </Fragment>",
102
+ "</Wix>"
103
+ };
104
+
105
+ var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
106
+
107
+ var messaging = new MockMessaging();
108
+ var converter = new WixConverter(messaging, 2, null, null);
109
+
110
+ var errors = converter.ConvertDocument(document);
111
+ Assert.Equal(1, errors);
112
+
113
+ var actualLines = UnformattedDocumentLines(document);
114
+ WixAssert.CompareLineByLine(expected, actualLines);
115
+ }
116
+
117
+ [Fact]
118
+ public void ConvertFrameworkBootstrapperApplicationRefWithExistingElement()
119
+ {
120
+ var parse = String.Join(Environment.NewLine,
121
+ "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi' xmlns:bal='http://schemas.microsoft.com/wix/BalExtension'>",
122
+ " <Fragment>",
123
+ " <BootstrapperApplicationRef Id='ManagedBootstrapperApplicationHost'>",
124
+ " <bal:WixManagedBootstrapperApplicationHost LogoFile='logo.png' />",
125
+ " </BootstrapperApplicationRef>",
126
+ " </Fragment>",
127
+ "</Wix>");
128
+
129
+ var expected = new[]
130
+ {
131
+ "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\" xmlns:bal=\"http://wixtoolset.org/schemas/v4/wxs/bal\">",
132
+ " <Fragment>",
133
+ " <BootstrapperApplication>",
134
+ " <bal:WixManagedBootstrapperApplicationHost LogoFile=\"logo.png\" />",
135
+ " </BootstrapperApplication>",
136
+ " </Fragment>",
137
+ "</Wix>"
138
+ };
139
+
140
+ var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
141
+
142
+ var messaging = new MockMessaging();
143
+ var converter = new WixConverter(messaging, 2, null, null);
144
+
145
+ var errors = converter.ConvertDocument(document);
146
+ Assert.Equal(3, errors);
147
+
148
+ var actualLines = UnformattedDocumentLines(document);
149
+ WixAssert.CompareLineByLine(expected, actualLines);
150
+ }
151
+
152
+ [Fact]
153
+ public void ConvertFrameworkBootstrapperApplicationRefWithoutExistingElement()
154
+ {
155
+ var parse = String.Join(Environment.NewLine,
156
+ "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi' xmlns:bal='http://schemas.microsoft.com/wix/BalExtension'>",
157
+ " <Fragment>",
158
+ " <BootstrapperApplicationRef Id='ManagedBootstrapperApplicationHost.RtfLicense.Minimal' />",
159
+ " </Fragment>",
160
+ "</Wix>");
161
+
162
+ var expected = new[]
163
+ {
164
+ "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\" xmlns:bal=\"http://wixtoolset.org/schemas/v4/wxs/bal\">",
165
+ " <Fragment>",
166
+ " <BootstrapperApplication>",
167
+ "<bal:WixManagedBootstrapperApplicationHost Theme=\"none\" />",
168
+ "</BootstrapperApplication>",
169
+ " </Fragment>",
170
+ "</Wix>"
171
+ };
172
+
173
+ var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
174
+
175
+ var messaging = new MockMessaging();
176
+ var converter = new WixConverter(messaging, 2, null, null);
177
+
178
+ var errors = converter.ConvertDocument(document);
179
+ Assert.Equal(3, errors);
180
+
181
+ var actualLines = UnformattedDocumentLines(document);
182
+ WixAssert.CompareLineByLine(expected, actualLines);
183
+ }
184
+
185
+ [Fact]
186
+ public void ConvertStandardBootstrapperApplicationRefWithExistingElement()
187
+ {
188
+ var parse = String.Join(Environment.NewLine,
189
+ "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi' xmlns:bal='http://schemas.microsoft.com/wix/BalExtension'>",
190
+ " <Fragment>",
191
+ " <BootstrapperApplicationRef Id='WixStandardBootstrapperApplication.Foundation'>",
192
+ " <bal:WixStandardBootstrapperApplication LaunchTarget='[InstallFolder]the.exe' />",
193
+ " </BootstrapperApplicationRef>",
194
+ " </Fragment>",
195
+ "</Wix>");
196
+
197
+ var expected = new[]
198
+ {
199
+ "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\" xmlns:bal=\"http://wixtoolset.org/schemas/v4/wxs/bal\">",
200
+ " <Fragment>",
201
+ " <BootstrapperApplication>",
202
+ " <bal:WixStandardBootstrapperApplication LaunchTarget=\"[InstallFolder]the.exe\" Theme=\"none\" />",
203
+ " </BootstrapperApplication>",
204
+ " </Fragment>",
205
+ "</Wix>"
206
+ };
207
+
208
+ var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
209
+
210
+ var messaging = new MockMessaging();
211
+ var converter = new WixConverter(messaging, 2, null, null);
212
+
213
+ var errors = converter.ConvertDocument(document);
214
+ Assert.Equal(3, errors);
215
+
216
+ var actualLines = UnformattedDocumentLines(document);
217
+ WixAssert.CompareLineByLine(expected, actualLines);
218
+ }
219
+
220
+ [Fact]
221
+ public void ConvertStandardBootstrapperApplicationRefWithoutExistingElement()
222
+ {
223
+ var parse = String.Join(Environment.NewLine,
224
+ "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi' xmlns:bal='http://schemas.microsoft.com/wix/BalExtension'>",
225
+ " <Fragment>",
226
+ " <BootstrapperApplicationRef Id='WixStandardBootstrapperApplication.RtfLicense' />",
227
+ " </Fragment>",
228
+ "</Wix>");
229
+
230
+ var expected = new[]
231
+ {
232
+ "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\" xmlns:bal=\"http://wixtoolset.org/schemas/v4/wxs/bal\">",
233
+ " <Fragment>",
234
+ " <BootstrapperApplication>",
235
+ "<bal:WixStandardBootstrapperApplication Theme=\"rtfLicense\" />",
236
+ "</BootstrapperApplication>",
237
+ " </Fragment>",
238
+ "</Wix>"
239
+ };
240
+
241
+ var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
242
+
243
+ var messaging = new MockMessaging();
244
+ var converter = new WixConverter(messaging, 2, null, null);
245
+
246
+ var errors = converter.ConvertDocument(document);
247
+ Assert.Equal(3, errors);
248
+
249
+ var actualLines = UnformattedDocumentLines(document);
250
+ WixAssert.CompareLineByLine(expected, actualLines);
251
+ }
252
+
253
[Fact]
254
public void CreateBootstrapperApplicationDllFromV3()
255
{