@joebigelow / wix / commits / 7378de43

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 {