aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Bal/wixext/BalCompiler.cs
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-05-03 15:55:48 -0700
committerRob Mensching <rob@firegiant.com>2021-05-03 15:55:48 -0700
commitba7bab476501c16e437b0aee71c1be02c3dda176 (patch)
tree814fba485c29a7dfe1adb396169e27ed641ef9a3 /src/ext/Bal/wixext/BalCompiler.cs
parent14987a72cc1a3493ca8f80693d273352fc314bd9 (diff)
downloadwix-ba7bab476501c16e437b0aee71c1be02c3dda176.tar.gz
wix-ba7bab476501c16e437b0aee71c1be02c3dda176.tar.bz2
wix-ba7bab476501c16e437b0aee71c1be02c3dda176.zip
Move Bal.wixext into ext
Diffstat (limited to 'src/ext/Bal/wixext/BalCompiler.cs')
-rw-r--r--src/ext/Bal/wixext/BalCompiler.cs923
1 files changed, 923 insertions, 0 deletions
diff --git a/src/ext/Bal/wixext/BalCompiler.cs b/src/ext/Bal/wixext/BalCompiler.cs
new file mode 100644
index 00000000..267345e7
--- /dev/null
+++ b/src/ext/Bal/wixext/BalCompiler.cs
@@ -0,0 +1,923 @@
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
3namespace WixToolset.Bal
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Xml.Linq;
8 using WixToolset.Bal.Symbols;
9 using WixToolset.Data;
10 using WixToolset.Data.Symbols;
11 using WixToolset.Extensibility;
12 using WixToolset.Extensibility.Data;
13
14 /// <summary>
15 /// The compiler for the WiX Toolset Bal Extension.
16 /// </summary>
17 public sealed class BalCompiler : BaseCompilerExtension
18 {
19 private readonly Dictionary<string, WixMbaPrereqInformationSymbol> prereqInfoSymbolsByPackageId;
20
21 private enum WixDotNetCoreBootstrapperApplicationHostTheme
22 {
23 Unknown,
24 None,
25 Standard,
26 }
27
28 private enum WixManagedBootstrapperApplicationHostTheme
29 {
30 Unknown,
31 None,
32 Standard,
33 }
34
35 private enum WixStandardBootstrapperApplicationTheme
36 {
37 Unknown,
38 HyperlinkLargeLicense,
39 HyperlinkLicense,
40 HyperlinkSidebarLicense,
41 None,
42 RtfLargeLicense,
43 RtfLicense,
44 }
45
46 /// <summary>
47 /// Instantiate a new BalCompiler.
48 /// </summary>
49 public BalCompiler()
50 {
51 this.prereqInfoSymbolsByPackageId = new Dictionary<string, WixMbaPrereqInformationSymbol>();
52 }
53
54 public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/bal";
55
56 /// <summary>
57 /// Processes an element for the Compiler.
58 /// </summary>
59 /// <param name="intermediate"></param>
60 /// <param name="section"></param>
61 /// <param name="parentElement">Parent element of element to process.</param>
62 /// <param name="element">Element to process.</param>
63 /// <param name="context">Extra information about the context in which this element is being parsed.</param>
64 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
65 {
66 switch (parentElement.Name.LocalName)
67 {
68 case "Bundle":
69 case "Fragment":
70 switch (element.Name.LocalName)
71 {
72 case "Condition":
73 this.ParseConditionElement(intermediate, section, element);
74 break;
75 case "ManagedBootstrapperApplicationPrereqInformation":
76 this.ParseMbaPrereqInfoElement(intermediate, section, element);
77 break;
78 default:
79 this.ParseHelper.UnexpectedElement(parentElement, element);
80 break;
81 }
82 break;
83 case "BootstrapperApplication":
84 switch (element.Name.LocalName)
85 {
86 case "WixStandardBootstrapperApplication":
87 this.ParseWixStandardBootstrapperApplicationElement(intermediate, section, element);
88 break;
89 case "WixManagedBootstrapperApplicationHost":
90 this.ParseWixManagedBootstrapperApplicationHostElement(intermediate, section, element);
91 break;
92 case "WixDotNetCoreBootstrapperApplicationHost":
93 this.ParseWixDotNetCoreBootstrapperApplicationHostElement(intermediate, section, element);
94 break;
95 default:
96 this.ParseHelper.UnexpectedElement(parentElement, element);
97 break;
98 }
99 break;
100 default:
101 this.ParseHelper.UnexpectedElement(parentElement, element);
102 break;
103 }
104 }
105
106 /// <summary>
107 /// Processes an attribute for the Compiler.
108 /// </summary>
109 /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
110 /// <param name="parentElement">Parent element of element to process.</param>
111 /// <param name="attribute">Attribute to process.</param>
112 /// <param name="context">Extra information about the context in which this element is being parsed.</param>
113 public override void ParseAttribute(Intermediate intermediate, IntermediateSection section, XElement parentElement, XAttribute attribute, IDictionary<string, string> context)
114 {
115 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(parentElement);
116 WixMbaPrereqInformationSymbol prereqInfo;
117
118 switch (parentElement.Name.LocalName)
119 {
120 case "ExePackage":
121 case "MsiPackage":
122 case "MspPackage":
123 case "MsuPackage":
124 string packageId;
125 if (!context.TryGetValue("PackageId", out packageId) || String.IsNullOrEmpty(packageId))
126 {
127 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, parentElement.Name.LocalName, "Id", attribute.Name.LocalName));
128 }
129 else
130 {
131 switch (attribute.Name.LocalName)
132 {
133 case "DisplayInternalUICondition":
134 switch (parentElement.Name.LocalName)
135 {
136 case "MsiPackage":
137 case "MspPackage":
138 var displayInternalUICondition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attribute);
139 section.AddSymbol(new WixBalPackageInfoSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, packageId))
140 {
141 PackageId = packageId,
142 DisplayInternalUICondition = displayInternalUICondition,
143 });
144 break;
145 default:
146 this.ParseHelper.UnexpectedAttribute(parentElement, attribute);
147 break;
148 }
149 break;
150 case "PrereqLicenseFile":
151
152 if (!this.prereqInfoSymbolsByPackageId.TryGetValue(packageId, out prereqInfo))
153 {
154 // at the time the extension attribute is parsed, the compiler might not yet have
155 // parsed the PrereqPackage attribute, so we need to get it directly from the parent element.
156 var prereqPackage = parentElement.Attribute(this.Namespace + "PrereqPackage");
157
158 if (null != prereqPackage && YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, prereqPackage))
159 {
160 prereqInfo = section.AddSymbol(new WixMbaPrereqInformationSymbol(sourceLineNumbers)
161 {
162 PackageId = packageId,
163 });
164
165 this.prereqInfoSymbolsByPackageId.Add(packageId, prereqInfo);
166 }
167 else
168 {
169 this.Messaging.Write(BalErrors.AttributeRequiresPrereqPackage(sourceLineNumbers, parentElement.Name.LocalName, "PrereqLicenseFile"));
170 break;
171 }
172 }
173
174 if (null != prereqInfo.LicenseUrl)
175 {
176 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, parentElement.Name.LocalName, "PrereqLicenseFile", "PrereqLicenseUrl"));
177 }
178 else
179 {
180 prereqInfo.LicenseFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attribute);
181 }
182 break;
183 case "PrereqLicenseUrl":
184
185 if (!this.prereqInfoSymbolsByPackageId.TryGetValue(packageId, out prereqInfo))
186 {
187 // at the time the extension attribute is parsed, the compiler might not yet have
188 // parsed the PrereqPackage attribute, so we need to get it directly from the parent element.
189 var prereqPackage = parentElement.Attribute(this.Namespace + "PrereqPackage");
190
191 if (null != prereqPackage && YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, prereqPackage))
192 {
193 prereqInfo = section.AddSymbol(new WixMbaPrereqInformationSymbol(sourceLineNumbers)
194 {
195 PackageId = packageId,
196 });
197
198 this.prereqInfoSymbolsByPackageId.Add(packageId, prereqInfo);
199 }
200 else
201 {
202 this.Messaging.Write(BalErrors.AttributeRequiresPrereqPackage(sourceLineNumbers, parentElement.Name.LocalName, "PrereqLicenseUrl"));
203 break;
204 }
205 }
206
207 if (null != prereqInfo.LicenseFile)
208 {
209 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, parentElement.Name.LocalName, "PrereqLicenseUrl", "PrereqLicenseFile"));
210 }
211 else
212 {
213 prereqInfo.LicenseUrl = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attribute);
214 }
215 break;
216 case "PrereqPackage":
217 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute))
218 {
219 if (!this.prereqInfoSymbolsByPackageId.TryGetValue(packageId, out prereqInfo))
220 {
221 prereqInfo = section.AddSymbol(new WixMbaPrereqInformationSymbol(sourceLineNumbers)
222 {
223 PackageId = packageId,
224 });
225
226 this.prereqInfoSymbolsByPackageId.Add(packageId, prereqInfo);
227 }
228 }
229 break;
230 default:
231 this.ParseHelper.UnexpectedAttribute(parentElement, attribute);
232 break;
233 }
234 }
235 break;
236 case "Payload":
237 string payloadId;
238 if (!context.TryGetValue("Id", out payloadId) || String.IsNullOrEmpty(payloadId))
239 {
240 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, parentElement.Name.LocalName, "Id", attribute.Name.LocalName));
241 }
242 else
243 {
244 switch (attribute.Name.LocalName)
245 {
246 case "BAFactoryAssembly":
247 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute))
248 {
249 // There can only be one.
250 var id = new Identifier(AccessModifier.Global, "TheBAFactoryAssembly");
251 section.AddSymbol(new WixBalBAFactoryAssemblySymbol(sourceLineNumbers, id)
252 {
253 PayloadId = payloadId,
254 });
255 }
256 break;
257 case "BAFunctions":
258 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute))
259 {
260 section.AddSymbol(new WixBalBAFunctionsSymbol(sourceLineNumbers)
261 {
262 PayloadId = payloadId,
263 });
264 }
265 break;
266 default:
267 this.ParseHelper.UnexpectedAttribute(parentElement, attribute);
268 break;
269 }
270 }
271 break;
272 case "Variable":
273 // at the time the extension attribute is parsed, the compiler might not yet have
274 // parsed the Name attribute, so we need to get it directly from the parent element.
275 var variableName = parentElement.Attribute("Name");
276 if (null == variableName)
277 {
278 this.Messaging.Write(ErrorMessages.ExpectedParentWithAttribute(sourceLineNumbers, "Variable", "Overridable", "Name"));
279 }
280 else
281 {
282 switch (attribute.Name.LocalName)
283 {
284 case "Overridable":
285 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute))
286 {
287 section.AddSymbol(new WixStdbaOverridableVariableSymbol(sourceLineNumbers)
288 {
289 Name = variableName.Value,
290 });
291 }
292 break;
293 default:
294 this.ParseHelper.UnexpectedAttribute(parentElement, attribute);
295 break;
296 }
297 }
298 break;
299 }
300 }
301
302 /// <summary>
303 /// Parses a Condition element for Bundles.
304 /// </summary>
305 /// <param name="node">The element to parse.</param>
306 private void ParseConditionElement(Intermediate intermediate, IntermediateSection section, XElement node)
307 {
308 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
309 string condition = null;
310 string message = null;
311
312 foreach (var attrib in node.Attributes())
313 {
314 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
315 {
316 switch (attrib.Name.LocalName)
317 {
318 case "Message":
319 message = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
320 break;
321 case "Condition":
322 condition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
323 break;
324 default:
325 this.ParseHelper.UnexpectedAttribute(node, attrib);
326 break;
327 }
328 }
329 else
330 {
331 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
332 }
333 }
334
335 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
336
337 // Error check the values.
338 if (String.IsNullOrEmpty(condition))
339 {
340 this.Messaging.Write(ErrorMessages.ConditionExpected(sourceLineNumbers, node.Name.LocalName));
341 }
342
343 if (null == message)
344 {
345 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Message"));
346 }
347
348 if (!this.Messaging.EncounteredError)
349 {
350 section.AddSymbol(new WixBalConditionSymbol(sourceLineNumbers)
351 {
352 Condition = condition,
353 Message = message,
354 });
355 }
356 }
357
358 /// <summary>
359 /// Parses a Condition element for Bundles.
360 /// </summary>
361 /// <param name="node">The element to parse.</param>
362 private void ParseMbaPrereqInfoElement(Intermediate intermediate, IntermediateSection section, XElement node)
363 {
364 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
365 string packageId = null;
366 string licenseFile = null;
367 string licenseUrl = null;
368
369 foreach (var attrib in node.Attributes())
370 {
371 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
372 {
373 switch (attrib.Name.LocalName)
374 {
375 case "LicenseFile":
376 licenseFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
377 break;
378 case "LicenseUrl":
379 licenseUrl = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
380 break;
381 case "PackageId":
382 packageId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
383 break;
384 default:
385 this.ParseHelper.UnexpectedAttribute(node, attrib);
386 break;
387 }
388 }
389 else
390 {
391 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
392 }
393 }
394
395 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
396
397 if (null == packageId)
398 {
399 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PackageId"));
400 }
401
402 if (null == licenseFile && null == licenseUrl ||
403 null != licenseFile && null != licenseUrl)
404 {
405 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "LicenseFile", "LicenseUrl", true));
406 }
407
408 if (!this.Messaging.EncounteredError)
409 {
410 section.AddSymbol(new WixMbaPrereqInformationSymbol(sourceLineNumbers)
411 {
412 PackageId = packageId,
413 LicenseFile = licenseFile,
414 LicenseUrl = licenseUrl,
415 });
416 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.WixBundlePackage, packageId);
417 }
418 }
419
420 /// <summary>
421 /// Parses a WixStandardBootstrapperApplication element for Bundles.
422 /// </summary>
423 /// <param name="node">The element to parse.</param>
424 private void ParseWixStandardBootstrapperApplicationElement(Intermediate intermediate, IntermediateSection section, XElement node)
425 {
426 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
427 string launchTarget = null;
428 string launchTargetElevatedId = null;
429 string launchArguments = null;
430 var launchHidden = YesNoType.NotSet;
431 string launchWorkingDir = null;
432 string licenseFile = null;
433 string licenseUrl = null;
434 string logoFile = null;
435 string logoSideFile = null;
436 WixStandardBootstrapperApplicationTheme? theme = null;
437 string themeFile = null;
438 string localizationFile = null;
439 var suppressOptionsUI = YesNoType.NotSet;
440 var suppressDowngradeFailure = YesNoType.NotSet;
441 var suppressRepair = YesNoType.NotSet;
442 var showVersion = YesNoType.NotSet;
443 var supportCacheOnly = YesNoType.NotSet;
444
445 foreach (var attrib in node.Attributes())
446 {
447 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
448 {
449 switch (attrib.Name.LocalName)
450 {
451 case "LaunchTarget":
452 launchTarget = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
453 break;
454 case "LaunchTargetElevatedId":
455 launchTargetElevatedId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
456 break;
457 case "LaunchArguments":
458 launchArguments = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
459 break;
460 case "LaunchHidden":
461 launchHidden = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
462 break;
463 case "LaunchWorkingFolder":
464 launchWorkingDir = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
465 break;
466 case "LicenseFile":
467 licenseFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
468 break;
469 case "LicenseUrl":
470 licenseUrl = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
471 break;
472 case "LogoFile":
473 logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
474 break;
475 case "LogoSideFile":
476 logoSideFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
477 break;
478 case "ThemeFile":
479 themeFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
480 break;
481 case "LocalizationFile":
482 localizationFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
483 break;
484 case "SuppressOptionsUI":
485 suppressOptionsUI = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
486 break;
487 case "SuppressDowngradeFailure":
488 suppressDowngradeFailure = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
489 break;
490 case "SuppressRepair":
491 suppressRepair = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
492 break;
493 case "ShowVersion":
494 showVersion = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
495 break;
496 case "SupportCacheOnly":
497 supportCacheOnly = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
498 break;
499 case "Theme":
500 var themeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
501 switch (themeValue)
502 {
503 case "hyperlinkLargeLicense":
504 theme = WixStandardBootstrapperApplicationTheme.HyperlinkLargeLicense;
505 break;
506 case "hyperlinkLicense":
507 theme = WixStandardBootstrapperApplicationTheme.HyperlinkLicense;
508 break;
509 case "hyperlinkSidebarLicense":
510 theme = WixStandardBootstrapperApplicationTheme.HyperlinkSidebarLicense;
511 break;
512 case "none":
513 theme = WixStandardBootstrapperApplicationTheme.None;
514 break;
515 case "rtfLargeLicense":
516 theme = WixStandardBootstrapperApplicationTheme.RtfLargeLicense;
517 break;
518 case "rtfLicense":
519 theme = WixStandardBootstrapperApplicationTheme.RtfLicense;
520 break;
521 default:
522 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Theme", themeValue, "hyperlinkLargeLicense", "hyperlinkLicense", "hyperlinkSidebarLicense", "none", "rtfLargeLicense", "rtfLicense"));
523 theme = WixStandardBootstrapperApplicationTheme.Unknown; // set a value to prevent expected attribute error below.
524 break;
525 }
526 break;
527 default:
528 this.ParseHelper.UnexpectedAttribute(node, attrib);
529 break;
530 }
531 }
532 else
533 {
534 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
535 }
536 }
537
538 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
539
540 if (!theme.HasValue)
541 {
542 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Theme"));
543 }
544
545 if (theme != WixStandardBootstrapperApplicationTheme.None && String.IsNullOrEmpty(licenseFile) && null == licenseUrl)
546 {
547 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "LicenseFile", "LicenseUrl", true));
548 }
549
550 if (!this.Messaging.EncounteredError)
551 {
552 if (!String.IsNullOrEmpty(launchTarget))
553 {
554 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchTarget"))
555 {
556 Value = launchTarget,
557 Type = WixBundleVariableType.Formatted,
558 });
559 }
560
561 if (!String.IsNullOrEmpty(launchTargetElevatedId))
562 {
563 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchTargetElevatedId"))
564 {
565 Value = launchTargetElevatedId,
566 Type = WixBundleVariableType.Formatted,
567 });
568 }
569
570 if (!String.IsNullOrEmpty(launchArguments))
571 {
572 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchArguments"))
573 {
574 Value = launchArguments,
575 Type = WixBundleVariableType.Formatted,
576 });
577 }
578
579 if (YesNoType.Yes == launchHidden)
580 {
581 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchHidden"))
582 {
583 Value = "yes",
584 Type = WixBundleVariableType.Formatted,
585 });
586 }
587
588
589 if (!String.IsNullOrEmpty(launchWorkingDir))
590 {
591 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchWorkingFolder"))
592 {
593 Value = launchWorkingDir,
594 Type = WixBundleVariableType.Formatted,
595 });
596 }
597
598 if (!String.IsNullOrEmpty(licenseFile))
599 {
600 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaLicenseRtf"))
601 {
602 Value = licenseFile,
603 });
604 }
605
606 if (null != licenseUrl)
607 {
608 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaLicenseUrl"))
609 {
610 Value = licenseUrl,
611 });
612 }
613
614 if (!String.IsNullOrEmpty(logoFile))
615 {
616 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaLogo"))
617 {
618 Value = logoFile,
619 });
620 }
621
622 if (!String.IsNullOrEmpty(logoSideFile))
623 {
624 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaLogoSide"))
625 {
626 Value = logoSideFile,
627 });
628 }
629
630 if (!String.IsNullOrEmpty(themeFile))
631 {
632 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaThemeXml"))
633 {
634 Value = themeFile,
635 });
636 }
637
638 if (!String.IsNullOrEmpty(localizationFile))
639 {
640 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaThemeWxl"))
641 {
642 Value = localizationFile,
643 });
644 }
645
646 if (YesNoType.Yes == suppressOptionsUI || YesNoType.Yes == suppressDowngradeFailure || YesNoType.Yes == suppressRepair || YesNoType.Yes == showVersion || YesNoType.Yes == supportCacheOnly)
647 {
648 var symbol = section.AddSymbol(new WixStdbaOptionsSymbol(sourceLineNumbers));
649 if (YesNoType.Yes == suppressOptionsUI)
650 {
651 symbol.SuppressOptionsUI = 1;
652 }
653
654 if (YesNoType.Yes == suppressDowngradeFailure)
655 {
656 symbol.SuppressDowngradeFailure = 1;
657 }
658
659 if (YesNoType.Yes == suppressRepair)
660 {
661 symbol.SuppressRepair = 1;
662 }
663
664 if (YesNoType.Yes == showVersion)
665 {
666 symbol.ShowVersion = 1;
667 }
668
669 if (YesNoType.Yes == supportCacheOnly)
670 {
671 symbol.SupportCacheOnly = 1;
672 }
673 }
674
675 var baId = "WixStandardBootstrapperApplication";
676 switch (theme)
677 {
678 case WixStandardBootstrapperApplicationTheme.HyperlinkLargeLicense:
679 baId = "WixStandardBootstrapperApplication.HyperlinkLargeLicense";
680 break;
681 case WixStandardBootstrapperApplicationTheme.HyperlinkLicense:
682 baId = "WixStandardBootstrapperApplication.HyperlinkLicense";
683 break;
684 case WixStandardBootstrapperApplicationTheme.HyperlinkSidebarLicense:
685 baId = "WixStandardBootstrapperApplication.HyperlinkSidebarLicense";
686 break;
687 case WixStandardBootstrapperApplicationTheme.RtfLargeLicense:
688 baId = "WixStandardBootstrapperApplication.RtfLargeLicense";
689 break;
690 case WixStandardBootstrapperApplicationTheme.RtfLicense:
691 baId = "WixStandardBootstrapperApplication.RtfLicense";
692 break;
693 }
694
695 this.CreateBARef(section, sourceLineNumbers, node, baId);
696 }
697 }
698
699 /// <summary>
700 /// Parses a WixManagedBootstrapperApplicationHost element for Bundles.
701 /// </summary>
702 /// <param name="node">The element to parse.</param>
703 private void ParseWixManagedBootstrapperApplicationHostElement(Intermediate intermediate, IntermediateSection section, XElement node)
704 {
705 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
706 string logoFile = null;
707 string themeFile = null;
708 string localizationFile = null;
709 WixManagedBootstrapperApplicationHostTheme? theme = null;
710
711 foreach (var attrib in node.Attributes())
712 {
713 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
714 {
715 switch (attrib.Name.LocalName)
716 {
717 case "LogoFile":
718 logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
719 break;
720 case "ThemeFile":
721 themeFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
722 break;
723 case "LocalizationFile":
724 localizationFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
725 break;
726 case "Theme":
727 var themeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
728 switch (themeValue)
729 {
730 case "none":
731 theme = WixManagedBootstrapperApplicationHostTheme.None;
732 break;
733 case "standard":
734 theme = WixManagedBootstrapperApplicationHostTheme.Standard;
735 break;
736 default:
737 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Theme", themeValue, "none", "standard"));
738 theme = WixManagedBootstrapperApplicationHostTheme.Unknown;
739 break;
740 }
741 break;
742 default:
743 this.ParseHelper.UnexpectedAttribute(node, attrib);
744 break;
745 }
746 }
747 else
748 {
749 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
750 }
751 }
752
753 if (!theme.HasValue)
754 {
755 theme = WixManagedBootstrapperApplicationHostTheme.Standard;
756 }
757
758 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
759
760 if (!this.Messaging.EncounteredError)
761 {
762 if (!String.IsNullOrEmpty(logoFile))
763 {
764 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "PreqbaLogo"))
765 {
766 Value = logoFile,
767 });
768 }
769
770 if (!String.IsNullOrEmpty(themeFile))
771 {
772 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "PreqbaThemeXml"))
773 {
774 Value = themeFile,
775 });
776 }
777
778 if (!String.IsNullOrEmpty(localizationFile))
779 {
780 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "PreqbaThemeWxl"))
781 {
782 Value = localizationFile,
783 });
784 }
785
786 var baId = "WixManagedBootstrapperApplicationHost";
787 switch (theme)
788 {
789 case WixManagedBootstrapperApplicationHostTheme.Standard:
790 baId = "WixManagedBootstrapperApplicationHost.Standard";
791 break;
792 }
793
794 this.CreateBARef(section, sourceLineNumbers, node, baId);
795 }
796 }
797
798 /// <summary>
799 /// Parses a WixDotNetCoreBootstrapperApplication element for Bundles.
800 /// </summary>
801 /// <param name="node">The element to parse.</param>
802 private void ParseWixDotNetCoreBootstrapperApplicationHostElement(Intermediate intermediate, IntermediateSection section, XElement node)
803 {
804 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
805 string logoFile = null;
806 string themeFile = null;
807 string localizationFile = null;
808 var selfContainedDeployment = YesNoType.NotSet;
809 WixDotNetCoreBootstrapperApplicationHostTheme? theme = null;
810
811 foreach (var attrib in node.Attributes())
812 {
813 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
814 {
815 switch (attrib.Name.LocalName)
816 {
817 case "LogoFile":
818 logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
819 break;
820 case "ThemeFile":
821 themeFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
822 break;
823 case "LocalizationFile":
824 localizationFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
825 break;
826 case "SelfContainedDeployment":
827 selfContainedDeployment = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
828 break;
829 case "Theme":
830 var themeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
831 switch (themeValue)
832 {
833 case "none":
834 theme = WixDotNetCoreBootstrapperApplicationHostTheme.None;
835 break;
836 case "standard":
837 theme = WixDotNetCoreBootstrapperApplicationHostTheme.Standard;
838 break;
839 default:
840 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Theme", themeValue, "none", "standard"));
841 theme = WixDotNetCoreBootstrapperApplicationHostTheme.Unknown;
842 break;
843 }
844 break;
845 default:
846 this.ParseHelper.UnexpectedAttribute(node, attrib);
847 break;
848 }
849 }
850 else
851 {
852 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
853 }
854 }
855
856 if (!theme.HasValue)
857 {
858 theme = WixDotNetCoreBootstrapperApplicationHostTheme.Standard;
859 }
860
861 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
862
863 if (!this.Messaging.EncounteredError)
864 {
865 if (!String.IsNullOrEmpty(logoFile))
866 {
867 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "DncPreqbaLogo"))
868 {
869 Value = logoFile,
870 });
871 }
872
873 if (!String.IsNullOrEmpty(themeFile))
874 {
875 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "DncPreqbaThemeXml"))
876 {
877 Value = themeFile,
878 });
879 }
880
881 if (!String.IsNullOrEmpty(localizationFile))
882 {
883 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "DncPreqbaThemeWxl"))
884 {
885 Value = localizationFile,
886 });
887 }
888
889 if (YesNoType.Yes == selfContainedDeployment)
890 {
891 section.AddSymbol(new WixDncOptionsSymbol(sourceLineNumbers)
892 {
893 SelfContainedDeployment = 1,
894 });
895 }
896
897 var baId = "WixDotNetCoreBootstrapperApplicationHost";
898 switch (theme)
899 {
900 case WixDotNetCoreBootstrapperApplicationHostTheme.Standard:
901 baId = "WixDotNetCoreBootstrapperApplicationHost.Standard";
902 break;
903 }
904
905 this.CreateBARef(section, sourceLineNumbers, node, baId);
906 }
907 }
908
909 private void CreateBARef(IntermediateSection section, SourceLineNumber sourceLineNumbers, XElement node, string name)
910 {
911 var id = this.ParseHelper.CreateIdentifierValueFromPlatform(name, this.Context.Platform, BurnPlatforms.X86 | BurnPlatforms.X64 | BurnPlatforms.ARM64);
912 if (id == null)
913 {
914 this.Messaging.Write(ErrorMessages.UnsupportedPlatformForElement(sourceLineNumbers, this.Context.Platform.ToString(), node.Name.LocalName));
915 }
916
917 if (!this.Messaging.EncounteredError)
918 {
919 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.WixBootstrapperApplication, id);
920 }
921 }
922 }
923}