main
cs 1,285 lines 62.9 KB
Raw
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
3 namespace WixToolset.BootstrapperApplications
4 {
5 using System;
6 using System.Collections.Generic;
7 using System.Xml.Linq;
8 using WixToolset.BootstrapperApplications.Symbols;
9 using WixToolset.Data;
10 using WixToolset.Data.Burn;
11 using WixToolset.Data.Symbols;
12 using WixToolset.Extensibility;
13 using WixToolset.Extensibility.Data;
14
15 /// <summary>
16 /// The compiler for the WiX Toolset Bal Extension.
17 /// </summary>
18 public sealed class BalCompiler : BaseCompilerExtension
19 {
20 private readonly Dictionary<string, WixBalPackageInfoSymbol> packageInfoSymbolsByPackageId = new Dictionary<string, WixBalPackageInfoSymbol>();
21 private readonly Dictionary<string, WixPrereqInformationSymbol> prereqInfoSymbolsByPackageId = new Dictionary<string, WixPrereqInformationSymbol>();
22
23 private enum WixPrerequisiteBootstrapperApplicationTheme
24 {
25 Unknown,
26 None,
27 Standard,
28 }
29
30 private enum WixInternalUIBootstrapperApplicationTheme
31 {
32 Unknown,
33 None,
34 Standard,
35 }
36
37 private enum WixStandardBootstrapperApplicationTheme
38 {
39 Unknown,
40 HyperlinkLargeLicense,
41 HyperlinkLicense,
42 HyperlinkSidebarLicense,
43 None,
44 RtfLargeLicense,
45 RtfLicense,
46 }
47
48 public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/bal";
49
50 /// <summary>
51 /// Processes an element for the Compiler.
52 /// </summary>
53 /// <param name="intermediate"></param>
54 /// <param name="section"></param>
55 /// <param name="parentElement">Parent element of element to process.</param>
56 /// <param name="element">Element to process.</param>
57 /// <param name="context">Extra information about the context in which this element is being parsed.</param>
58 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
59 {
60 this.ParsePossibleKeyPathElement(intermediate, section, parentElement, element, context);
61 }
62
63 /// <summary>
64 /// Processes an element for the Compiler.
65 /// </summary>
66 /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
67 /// <param name="parentElement">Parent element of element to process.</param>
68 /// <param name="element">Element to process.</param>
69 /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
70 public override IComponentKeyPath ParsePossibleKeyPathElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
71 {
72 IComponentKeyPath exePayloadRef = null;
73
74 switch (parentElement.Name.LocalName)
75 {
76 case "Bundle":
77 case "Fragment":
78 switch (element.Name.LocalName)
79 {
80 case "BootstrapperApplicationPrerequisiteInformation":
81 this.ParseBootstrapperApplicationPrerequisiteInformationElement(intermediate, section, element);
82 break;
83 case "Condition":
84 this.ParseConditionElement(intermediate, section, element);
85 break;
86 case "ManagedBootstrapperApplicationPrereqInformation":
87 this.Messaging.Write(WarningMessages.DeprecatedElement(this.ParseHelper.GetSourceLineNumbers(element), element.Name.LocalName, "BootstrapperApplicationPrerequisiteInformation"));
88 this.ParseBootstrapperApplicationPrerequisiteInformationElement(intermediate, section, element);
89 break;
90 default:
91 this.ParseHelper.UnexpectedElement(parentElement, element);
92 break;
93 }
94 break;
95 case "BootstrapperApplication":
96 switch (element.Name.LocalName)
97 {
98 case "WixInternalUIBootstrapperApplication":
99 exePayloadRef = this.ParseWixInternalUIBootstrapperApplicationElement(intermediate, section, element);
100 break;
101 case "WixPrerequisiteBootstrapperApplication":
102 this.ParseWixPrerequisiteBootstrapperApplicationElement(intermediate, section, element, context);
103 break;
104 case "WixStandardBootstrapperApplication":
105 exePayloadRef = this.ParseWixStandardBootstrapperApplicationElement(intermediate, section, element);
106 break;
107 case "WixManagedBootstrapperApplicationHost":
108 this.Messaging.Write(WarningMessages.DeprecatedElement(this.ParseHelper.GetSourceLineNumbers(element), element.Name.LocalName));
109 break;
110 case "WixDotNetCoreBootstrapperApplicationHost":
111 this.Messaging.Write(WarningMessages.DeprecatedElement(this.ParseHelper.GetSourceLineNumbers(element), element.Name.LocalName));
112 break;
113 default:
114 this.ParseHelper.UnexpectedElement(parentElement, element);
115 break;
116 }
117 break;
118 default:
119 this.ParseHelper.UnexpectedElement(parentElement, element);
120 break;
121 }
122
123 return exePayloadRef;
124 }
125
126 /// <summary>
127 /// Processes an attribute for the Compiler.
128 /// </summary>
129 /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
130 /// <param name="parentElement">Parent element of element to process.</param>
131 /// <param name="attribute">Attribute to process.</param>
132 /// <param name="context">Extra information about the context in which this element is being parsed.</param>
133 public override void ParseAttribute(Intermediate intermediate, IntermediateSection section, XElement parentElement, XAttribute attribute, IDictionary<string, string> context)
134 {
135 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(parentElement);
136
137 switch (parentElement.Name.LocalName)
138 {
139 case "Bundle":
140 switch (attribute.Name.LocalName)
141 {
142 case "CommandLineVariables":
143 WixStdbaCommandLineVariableType? variableType = null;
144
145 var commandLineVariablesValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attribute);
146 switch (commandLineVariablesValue)
147 {
148 case "caseInsensitive":
149 variableType = WixStdbaCommandLineVariableType.CaseInsensitive;
150 break;
151 case "caseSensitive":
152 variableType = WixStdbaCommandLineVariableType.CaseSensitive;
153 break;
154 default:
155 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, parentElement.Name.LocalName, attribute.Name.LocalName, commandLineVariablesValue, "caseInsensitive", "caseSensitive"));
156 break;
157 }
158
159 if (variableType.HasValue)
160 {
161 // There can only be one.
162 var id = new Identifier(AccessModifier.Global, "WixStdbaCommandLineVariableType");
163 section.AddSymbol(new WixStdbaCommandLineSymbol(sourceLineNumbers, id)
164 {
165 VariableType = variableType.Value,
166 });
167 }
168
169 break;
170 default:
171 this.ParseHelper.UnexpectedAttribute(parentElement, attribute);
172 break;
173 }
174 break;
175 case "BundlePackage":
176 case "ExePackage":
177 case "MsiPackage":
178 case "MspPackage":
179 case "MsuPackage":
180 string packageId;
181 if (!context.TryGetValue("PackageId", out packageId) || String.IsNullOrEmpty(packageId))
182 {
183 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, parentElement.Name.LocalName, "Id", attribute.Name.LocalName));
184 }
185 else
186 {
187 switch (attribute.Name.LocalName)
188 {
189 case "DisplayInternalUICondition":
190 switch (parentElement.Name.LocalName)
191 {
192 case "MsiPackage":
193 case "MspPackage":
194 var displayInternalUICondition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attribute);
195 var packageInfo = this.GetBalPackageInfoSymbol(section, sourceLineNumbers, packageId);
196 packageInfo.DisplayInternalUICondition = displayInternalUICondition;
197 break;
198 default:
199 this.ParseHelper.UnexpectedAttribute(parentElement, attribute);
200 break;
201 }
202 break;
203 case "PrimaryPackageType":
204 {
205 var primaryPackageType = BalPrimaryPackageType.None;
206 var primaryPackageTypeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attribute);
207 switch (primaryPackageTypeValue)
208 {
209 case "default":
210 primaryPackageType = BalPrimaryPackageType.Default;
211 break;
212 case "x86":
213 primaryPackageType = BalPrimaryPackageType.X86;
214 break;
215 case "x64":
216 primaryPackageType = BalPrimaryPackageType.X64;
217 break;
218 case "arm64":
219 primaryPackageType = BalPrimaryPackageType.ARM64;
220 break;
221 default:
222 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, parentElement.Name.LocalName, "PrimaryPackageType", primaryPackageTypeValue, "default", "x86", "x64", "arm64"));
223 break;
224 }
225
226 // at the time the extension attribute is parsed, the compiler might not yet have
227 // parsed the PrereqPackage attribute, so we need to get it directly from the parent element.
228 var prereqPackage = parentElement.Attribute(this.Namespace + "PrereqPackage");
229 var prereqInfo = this.GetMbaPrereqInformationSymbol(section, sourceLineNumbers, prereqPackage, packageId);
230 if (prereqInfo != null)
231 {
232 this.Messaging.Write(ErrorMessages.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, parentElement.Name.LocalName, "PrereqPackage", "yes", "PrimaryPackageType"));
233 }
234 else
235 {
236 var packageInfo = this.GetBalPackageInfoSymbol(section, sourceLineNumbers, packageId);
237 packageInfo.PrimaryPackageType = primaryPackageType;
238 }
239 break;
240 }
241 case "PrereqLicenseFile":
242 {
243 // at the time the extension attribute is parsed, the compiler might not yet have
244 // parsed the PrereqPackage attribute, so we need to get it directly from the parent element.
245 var prereqPackage = parentElement.Attribute(this.Namespace + "PrereqPackage");
246 var prereqInfo = this.GetMbaPrereqInformationSymbol(section, sourceLineNumbers, prereqPackage, packageId);
247 if (prereqInfo == null)
248 {
249 this.Messaging.Write(BalErrors.AttributeRequiresPrereqPackage(sourceLineNumbers, parentElement.Name.LocalName, "PrereqLicenseFile"));
250 }
251 else if (null != prereqInfo.LicenseUrl)
252 {
253 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, parentElement.Name.LocalName, "PrereqLicenseFile", "PrereqLicenseUrl"));
254 }
255 else
256 {
257 prereqInfo.LicenseFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attribute);
258 }
259 break;
260 }
261 case "PrereqLicenseUrl":
262 {
263 // at the time the extension attribute is parsed, the compiler might not yet have
264 // parsed the PrereqPackage attribute, so we need to get it directly from the parent element.
265 var prereqPackage = parentElement.Attribute(this.Namespace + "PrereqPackage");
266 var prereqInfo = this.GetMbaPrereqInformationSymbol(section, sourceLineNumbers, prereqPackage, packageId);
267
268 if (prereqInfo == null)
269 {
270 this.Messaging.Write(BalErrors.AttributeRequiresPrereqPackage(sourceLineNumbers, parentElement.Name.LocalName, "PrereqLicenseUrl"));
271 }
272 else if (null != prereqInfo.LicenseFile)
273 {
274 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, parentElement.Name.LocalName, "PrereqLicenseUrl", "PrereqLicenseFile"));
275 }
276 else
277 {
278 prereqInfo.LicenseUrl = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attribute);
279 }
280 break;
281 }
282 case "PrereqPackage":
283 this.GetMbaPrereqInformationSymbol(section, sourceLineNumbers, attribute, packageId);
284 break;
285 default:
286 this.ParseHelper.UnexpectedAttribute(parentElement, attribute);
287 break;
288 }
289 }
290 break;
291 case "Payload":
292 string payloadId;
293 if (!context.TryGetValue("Id", out payloadId) || String.IsNullOrEmpty(payloadId))
294 {
295 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, parentElement.Name.LocalName, "Id", attribute.Name.LocalName));
296 }
297 else
298 {
299 switch (attribute.Name.LocalName)
300 {
301 case "BAFactoryAssembly":
302 this.Messaging.Write(BalWarnings.DeprecatedBAFactoryAssemblyAttribute(this.ParseHelper.GetSourceLineNumbers(parentElement), parentElement.Name.LocalName, attribute.Name.LocalName));
303 break;
304 case "BAFunctions":
305 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute))
306 {
307 section.AddSymbol(new WixBalBAFunctionsSymbol(sourceLineNumbers)
308 {
309 PayloadId = payloadId,
310 });
311 }
312 break;
313 default:
314 this.ParseHelper.UnexpectedAttribute(parentElement, attribute);
315 break;
316 }
317 }
318 break;
319 case "Variable":
320 // at the time the extension attribute is parsed, the compiler might not yet have
321 // parsed the Name attribute, so we need to get it directly from the parent element.
322 var variableName = parentElement.Attribute("Name");
323 if (null == variableName)
324 {
325 this.Messaging.Write(ErrorMessages.ExpectedParentWithAttribute(sourceLineNumbers, "Variable", "Overridable", "Name"));
326 }
327 else
328 {
329 switch (attribute.Name.LocalName)
330 {
331 case "Overridable":
332 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute))
333 {
334 section.AddSymbol(new WixStdbaOverridableVariableSymbol(sourceLineNumbers)
335 {
336 Name = variableName.Value,
337 });
338 }
339 break;
340 default:
341 this.ParseHelper.UnexpectedAttribute(parentElement, attribute);
342 break;
343 }
344 }
345 break;
346 }
347 }
348
349 private WixBalPackageInfoSymbol GetBalPackageInfoSymbol(IntermediateSection section, SourceLineNumber sourceLineNumbers, string packageId)
350 {
351 if (!this.packageInfoSymbolsByPackageId.TryGetValue(packageId, out var packageInfo))
352 {
353 packageInfo = section.AddSymbol(new WixBalPackageInfoSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, packageId))
354 {
355 PackageId = packageId,
356 });
357
358 this.packageInfoSymbolsByPackageId.Add(packageId, packageInfo);
359 }
360
361 return packageInfo;
362 }
363
364 private WixPrereqInformationSymbol GetMbaPrereqInformationSymbol(IntermediateSection section, SourceLineNumber sourceLineNumbers, XAttribute prereqAttribute, string packageId)
365 {
366 WixPrereqInformationSymbol prereqInfo = null;
367
368 if (prereqAttribute != null && YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, prereqAttribute))
369 {
370 if (!this.prereqInfoSymbolsByPackageId.TryGetValue(packageId, out prereqInfo))
371 {
372 prereqInfo = section.AddSymbol(new WixPrereqInformationSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, packageId))
373 {
374 PackageId = packageId,
375 });
376
377 this.prereqInfoSymbolsByPackageId.Add(packageId, prereqInfo);
378 }
379 }
380
381 return prereqInfo;
382 }
383
384 /// <summary>
385 /// Parses a Condition element for Bundles.
386 /// </summary>
387 /// <param name="node">The element to parse.</param>
388 private void ParseConditionElement(Intermediate intermediate, IntermediateSection section, XElement node)
389 {
390 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
391 string condition = null;
392 string message = null;
393
394 foreach (var attrib in node.Attributes())
395 {
396 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
397 {
398 switch (attrib.Name.LocalName)
399 {
400 case "Message":
401 message = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
402 break;
403 case "Condition":
404 condition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
405 break;
406 default:
407 this.ParseHelper.UnexpectedAttribute(node, attrib);
408 break;
409 }
410 }
411 else
412 {
413 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
414 }
415 }
416
417 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
418
419 // Error check the values.
420 if (String.IsNullOrEmpty(condition))
421 {
422 this.Messaging.Write(ErrorMessages.ConditionExpected(sourceLineNumbers, node.Name.LocalName));
423 }
424
425 if (null == message)
426 {
427 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Message"));
428 }
429
430 if (!this.Messaging.EncounteredError)
431 {
432 section.AddSymbol(new WixBalConditionSymbol(sourceLineNumbers)
433 {
434 Condition = condition,
435 Message = message,
436 });
437 }
438 }
439
440 /// <summary>
441 /// Parses a Condition element for Bundles.
442 /// </summary>
443 /// <param name="node">The element to parse.</param>
444 private void ParseBootstrapperApplicationPrerequisiteInformationElement(Intermediate intermediate, IntermediateSection section, XElement node)
445 {
446 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
447 string packageId = null;
448 string licenseFile = null;
449 string licenseUrl = null;
450
451 foreach (var attrib in node.Attributes())
452 {
453 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
454 {
455 switch (attrib.Name.LocalName)
456 {
457 case "LicenseFile":
458 licenseFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
459 break;
460 case "LicenseUrl":
461 licenseUrl = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
462 break;
463 case "PackageId":
464 packageId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
465 break;
466 default:
467 this.ParseHelper.UnexpectedAttribute(node, attrib);
468 break;
469 }
470 }
471 else
472 {
473 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
474 }
475 }
476
477 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
478
479 if (null == packageId)
480 {
481 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PackageId"));
482 }
483
484 if (null == licenseFile && null == licenseUrl ||
485 null != licenseFile && null != licenseUrl)
486 {
487 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "LicenseFile", "LicenseUrl", true));
488 }
489
490 if (!this.Messaging.EncounteredError)
491 {
492 section.AddSymbol(new WixPrereqInformationSymbol(sourceLineNumbers)
493 {
494 PackageId = packageId,
495 LicenseFile = licenseFile,
496 LicenseUrl = licenseUrl,
497 });
498 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.WixBundlePackage, packageId);
499 }
500 }
501
502 private IComponentKeyPath ParseWixInternalUIBootstrapperApplicationElement(Intermediate intermediate, IntermediateSection section, XElement node)
503 {
504 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
505 var theme = WixInternalUIBootstrapperApplicationTheme.Standard;
506 string themeFile = null;
507 string logoFile = null;
508 string localizationFile = null;
509
510 IComponentKeyPath exePayloadRef = null;
511
512 foreach (var attrib in node.Attributes())
513 {
514 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
515 {
516 switch (attrib.Name.LocalName)
517 {
518 case "LogoFile":
519 logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
520 break;
521 case "ThemeFile":
522 themeFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
523 break;
524 case "LocalizationFile":
525 localizationFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
526 break;
527 case "Theme":
528 var themeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
529 switch (themeValue)
530 {
531 case "none":
532 theme = WixInternalUIBootstrapperApplicationTheme.None;
533 break;
534 case "standard":
535 theme = WixInternalUIBootstrapperApplicationTheme.Standard;
536 break;
537 default:
538 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Theme", themeValue, "none", "standard"));
539 theme = WixInternalUIBootstrapperApplicationTheme.Unknown;
540 break;
541 }
542 break;
543 default:
544 this.ParseHelper.UnexpectedAttribute(node, attrib);
545 break;
546 }
547 }
548 else
549 {
550 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
551 }
552 }
553
554 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
555
556 if (!this.Messaging.EncounteredError)
557 {
558 if (!String.IsNullOrEmpty(logoFile))
559 {
560 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixIuibaLogo"))
561 {
562 Value = logoFile,
563 });
564 }
565
566 if (!String.IsNullOrEmpty(themeFile))
567 {
568 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixIuibaThemeXml"))
569 {
570 Value = themeFile,
571 });
572 }
573
574 if (!String.IsNullOrEmpty(localizationFile))
575 {
576 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixIuibaThemeWxl"))
577 {
578 Value = localizationFile,
579 });
580 }
581
582 switch (theme)
583 {
584 case WixInternalUIBootstrapperApplicationTheme.Standard:
585 this.CreatePayloadGroupRef(section, sourceLineNumbers, node, "WixIuibaStandardPayloads", platformSpecific: false);
586 break;
587 }
588
589 section.AddSymbol(new WixBalBootstrapperApplicationSymbol(sourceLineNumbers)
590 {
591 Type = WixBalBootstrapperApplicationType.InternalUi,
592 });
593
594 section.AddSymbol(new WixPrereqOptionsSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixPrereqOptions"))
595 {
596 Primary = 1,
597 HandleHelp = 1,
598 HandleLayout = 1,
599 });
600
601 var exePayloadId = this.CreatePayloadGroupRef(section, sourceLineNumbers, node, "WixInternalUIBootstrapperApplication", platformSpecific: true);
602
603 exePayloadRef = this.CreateComponentKeyPath();
604 exePayloadRef.Id = new Identifier(AccessModifier.Section, exePayloadId);
605 exePayloadRef.Explicit = true; // Internal UI BA is always secondary because the PrereqBA is always primary to handle the help and layout options.
606 exePayloadRef.Type = PossibleKeyPathType.File;
607 }
608
609 return exePayloadRef;
610 }
611
612 /// <summary>
613 /// Parses a WixStandardBootstrapperApplication element for Bundles.
614 /// </summary>
615 /// <param name="node">The element to parse.</param>
616 private IComponentKeyPath ParseWixStandardBootstrapperApplicationElement(Intermediate intermediate, IntermediateSection section, XElement node)
617 {
618 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
619 string launchTarget = null;
620 string launchTargetElevatedId = null;
621 string launchArguments = null;
622 var launchHidden = YesNoType.NotSet;
623 string launchWorkingDir = null;
624 string licenseFile = null;
625 string licenseUrl = null;
626 string logoFile = null;
627 string logoSideFile = null;
628 WixStandardBootstrapperApplicationTheme? theme = null;
629 string themeFile = null;
630 string localizationFile = null;
631 var suppressOptionsUI = YesNoType.NotSet;
632 var suppressDowngradeFailure = YesNoType.NotSet;
633 var suppressRepair = YesNoType.NotSet;
634 var showVersion = YesNoType.NotSet;
635 var supportCacheOnly = YesNoType.NotSet;
636
637 IComponentKeyPath exePayloadRef = null;
638
639 foreach (var attrib in node.Attributes())
640 {
641 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
642 {
643 switch (attrib.Name.LocalName)
644 {
645 case "LaunchTarget":
646 launchTarget = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
647 break;
648 case "LaunchTargetElevatedId":
649 launchTargetElevatedId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
650 break;
651 case "LaunchArguments":
652 launchArguments = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
653 break;
654 case "LaunchHidden":
655 launchHidden = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
656 break;
657 case "LaunchWorkingFolder":
658 launchWorkingDir = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
659 break;
660 case "LicenseFile":
661 licenseFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
662 break;
663 case "LicenseUrl":
664 licenseUrl = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
665 break;
666 case "LogoFile":
667 logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
668 break;
669 case "LogoSideFile":
670 logoSideFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
671 break;
672 case "ThemeFile":
673 themeFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
674 break;
675 case "LocalizationFile":
676 localizationFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
677 break;
678 case "SuppressOptionsUI":
679 suppressOptionsUI = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
680 break;
681 case "SuppressDowngradeFailure":
682 suppressDowngradeFailure = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
683 break;
684 case "SuppressRepair":
685 suppressRepair = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
686 break;
687 case "ShowVersion":
688 showVersion = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
689 break;
690 case "SupportCacheOnly":
691 supportCacheOnly = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
692 break;
693 case "Theme":
694 var themeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
695 switch (themeValue)
696 {
697 case "hyperlinkLargeLicense":
698 theme = WixStandardBootstrapperApplicationTheme.HyperlinkLargeLicense;
699 break;
700 case "hyperlinkLicense":
701 theme = WixStandardBootstrapperApplicationTheme.HyperlinkLicense;
702 break;
703 case "hyperlinkSidebarLicense":
704 theme = WixStandardBootstrapperApplicationTheme.HyperlinkSidebarLicense;
705 break;
706 case "none":
707 theme = WixStandardBootstrapperApplicationTheme.None;
708 break;
709 case "rtfLargeLicense":
710 theme = WixStandardBootstrapperApplicationTheme.RtfLargeLicense;
711 break;
712 case "rtfLicense":
713 theme = WixStandardBootstrapperApplicationTheme.RtfLicense;
714 break;
715 default:
716 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Theme", themeValue, "hyperlinkLargeLicense", "hyperlinkLicense", "hyperlinkSidebarLicense", "none", "rtfLargeLicense", "rtfLicense"));
717 theme = WixStandardBootstrapperApplicationTheme.Unknown; // set a value to prevent expected attribute error below.
718 break;
719 }
720 break;
721 default:
722 this.ParseHelper.UnexpectedAttribute(node, attrib);
723 break;
724 }
725 }
726 else
727 {
728 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
729 }
730 }
731
732 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
733
734 if (!theme.HasValue)
735 {
736 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Theme"));
737 }
738
739 if (theme != WixStandardBootstrapperApplicationTheme.None && String.IsNullOrEmpty(licenseFile) && null == licenseUrl)
740 {
741 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "LicenseFile", "LicenseUrl", true));
742 }
743
744 if (!this.Messaging.EncounteredError)
745 {
746 if (!String.IsNullOrEmpty(launchTarget))
747 {
748 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchTarget"))
749 {
750 Value = launchTarget,
751 Type = WixBundleVariableType.Formatted,
752 });
753 }
754
755 if (!String.IsNullOrEmpty(launchTargetElevatedId))
756 {
757 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchTargetElevatedId"))
758 {
759 Value = launchTargetElevatedId,
760 Type = WixBundleVariableType.Formatted,
761 });
762 }
763
764 if (!String.IsNullOrEmpty(launchArguments))
765 {
766 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchArguments"))
767 {
768 Value = launchArguments,
769 Type = WixBundleVariableType.Formatted,
770 });
771 }
772
773 if (YesNoType.Yes == launchHidden)
774 {
775 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchHidden"))
776 {
777 Value = "yes",
778 Type = WixBundleVariableType.Formatted,
779 });
780 }
781
782
783 if (!String.IsNullOrEmpty(launchWorkingDir))
784 {
785 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchWorkingFolder"))
786 {
787 Value = launchWorkingDir,
788 Type = WixBundleVariableType.Formatted,
789 });
790 }
791
792 if (!String.IsNullOrEmpty(licenseFile))
793 {
794 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaLicenseRtf"))
795 {
796 Value = licenseFile,
797 });
798 }
799
800 if (null != licenseUrl)
801 {
802 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaLicenseUrl"))
803 {
804 Value = licenseUrl,
805 });
806 }
807
808 if (!String.IsNullOrEmpty(logoFile))
809 {
810 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaLogo"))
811 {
812 Value = logoFile,
813 });
814 }
815
816 if (!String.IsNullOrEmpty(logoSideFile))
817 {
818 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaLogoSide"))
819 {
820 Value = logoSideFile,
821 });
822 }
823
824 if (!String.IsNullOrEmpty(themeFile))
825 {
826 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaThemeXml"))
827 {
828 Value = themeFile,
829 });
830 }
831
832 if (!String.IsNullOrEmpty(localizationFile))
833 {
834 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaThemeWxl"))
835 {
836 Value = localizationFile,
837 });
838 }
839
840 if (YesNoType.Yes == suppressOptionsUI || YesNoType.Yes == suppressDowngradeFailure || YesNoType.Yes == suppressRepair || YesNoType.Yes == showVersion || YesNoType.Yes == supportCacheOnly)
841 {
842 var symbol = section.AddSymbol(new WixStdbaOptionsSymbol(sourceLineNumbers));
843 if (YesNoType.Yes == suppressOptionsUI)
844 {
845 symbol.SuppressOptionsUI = 1;
846 }
847
848 if (YesNoType.Yes == suppressDowngradeFailure)
849 {
850 symbol.SuppressDowngradeFailure = 1;
851 }
852
853 if (YesNoType.Yes == suppressRepair)
854 {
855 symbol.SuppressRepair = 1;
856 }
857
858 if (YesNoType.Yes == showVersion)
859 {
860 symbol.ShowVersion = 1;
861 }
862
863 if (YesNoType.Yes == supportCacheOnly)
864 {
865 symbol.SupportCacheOnly = 1;
866 }
867 }
868
869 switch (theme)
870 {
871 case WixStandardBootstrapperApplicationTheme.HyperlinkLargeLicense:
872 this.CreatePayloadGroupRef(section, sourceLineNumbers, node, "WixStdbaHyperlinkLargeLicensePayloads", platformSpecific: false);
873 break;
874 case WixStandardBootstrapperApplicationTheme.HyperlinkLicense:
875 this.CreatePayloadGroupRef(section, sourceLineNumbers, node, "WixStdbaHyperlinkLicensePayloads", platformSpecific: false);
876 break;
877 case WixStandardBootstrapperApplicationTheme.HyperlinkSidebarLicense:
878 this.CreatePayloadGroupRef(section, sourceLineNumbers, node, "WixStdbaHyperlinkSidebarLicensePayloads", platformSpecific: false);
879 break;
880 case WixStandardBootstrapperApplicationTheme.RtfLargeLicense:
881 this.CreatePayloadGroupRef(section, sourceLineNumbers, node, "WixStdbaRtfLargeLicensePayloads", platformSpecific: false);
882 break;
883 case WixStandardBootstrapperApplicationTheme.RtfLicense:
884 this.CreatePayloadGroupRef(section, sourceLineNumbers, node, "WixStdbaRtfLicensePayloads", platformSpecific: false);
885 break;
886 }
887
888 section.AddSymbol(new WixBalBootstrapperApplicationSymbol(sourceLineNumbers)
889 {
890 Type = WixBalBootstrapperApplicationType.Standard,
891 });
892
893 var exePayloadId = this.CreatePayloadGroupRef(section, sourceLineNumbers, node, "WixStandardBootstrapperApplication", platformSpecific: true);
894
895 exePayloadRef = this.CreateComponentKeyPath();
896 exePayloadRef.Id = new Identifier(AccessModifier.Section, exePayloadId);
897 exePayloadRef.Type = PossibleKeyPathType.File;
898 }
899
900 return exePayloadRef;
901 }
902
903 /// <summary>
904 /// Parses a WixManagedBootstrapperApplicationHost element for Bundles.
905 /// </summary>
906 /// <param name="node">The element to parse.</param>
907 private void ParseWixPrerequisiteBootstrapperApplicationElement(Intermediate intermediate, IntermediateSection section, XElement node, IDictionary<string, string> context)
908 {
909 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
910 string logoFile = null;
911 string themeFile = null;
912 string localizationFile = null;
913 var theme = WixPrerequisiteBootstrapperApplicationTheme.Standard;
914
915 foreach (var attrib in node.Attributes())
916 {
917 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
918 {
919 switch (attrib.Name.LocalName)
920 {
921 case "LogoFile":
922 logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
923 break;
924 case "ThemeFile":
925 themeFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
926 break;
927 case "LocalizationFile":
928 localizationFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
929 break;
930 case "Theme":
931 var themeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
932 switch (themeValue)
933 {
934 case "none":
935 theme = WixPrerequisiteBootstrapperApplicationTheme.None;
936 break;
937 case "standard":
938 theme = WixPrerequisiteBootstrapperApplicationTheme.Standard;
939 break;
940 default:
941 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Theme", themeValue, "none", "standard"));
942 theme = WixPrerequisiteBootstrapperApplicationTheme.Unknown;
943 break;
944 }
945 break;
946 default:
947 this.ParseHelper.UnexpectedAttribute(node, attrib);
948 break;
949 }
950 }
951 else
952 {
953 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
954 }
955 }
956
957 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
958
959 if (!this.Messaging.EncounteredError)
960 {
961 if (!String.IsNullOrEmpty(logoFile))
962 {
963 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixPreqbaLogo"))
964 {
965 Value = logoFile,
966 });
967 }
968
969 if (!String.IsNullOrEmpty(themeFile))
970 {
971 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixPreqbaThemeXml"))
972 {
973 Value = themeFile,
974 });
975 }
976
977 if (!String.IsNullOrEmpty(localizationFile))
978 {
979 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixPreqbaThemeWxl"))
980 {
981 Value = localizationFile,
982 });
983 }
984
985 switch (theme)
986 {
987 case WixPrerequisiteBootstrapperApplicationTheme.Standard:
988 this.CreatePayloadGroupRef(section, sourceLineNumbers, node, "WixPreqbaStandardPayloads", platformSpecific: false);
989 break;
990 }
991
992 section.AddSymbol(new WixBalBootstrapperApplicationSymbol(sourceLineNumbers)
993 {
994 Type = WixBalBootstrapperApplicationType.Prerequisite,
995 });
996
997 var primary = context.TryGetValue("Secondary", out var parentSecondaryValue) && "True".Equals(parentSecondaryValue, StringComparison.OrdinalIgnoreCase) ? true : false;
998
999 var baId = this.CreateIdentifierFromPlatform(sourceLineNumbers, node, primary ? "WixPrereqBootstrapperApplication.Primary" : "WixPrereqBootstrapperApplication.Secondary");
1000
1001 if (!String.IsNullOrEmpty(baId))
1002 {
1003 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.WixBootstrapperApplication, baId);
1004 }
1005
1006 if (primary)
1007 {
1008 section.AddSymbol(new WixPrereqOptionsSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixPrereqOptions"))
1009 {
1010 Primary = 1
1011 });
1012 }
1013 }
1014 }
1015
1016 #if DELETE
1017 /// <summary>
1018 /// Parses a WixManagedBootstrapperApplicationHost element for Bundles.
1019 /// </summary>
1020 /// <param name="node">The element to parse.</param>
1021 private IComponentKeyPath ParseWixManagedBootstrapperApplicationHostElement(Intermediate intermediate, IntermediateSection section, XElement node)
1022 {
1023 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1024 bool alwaysInstallPrereqs = false;
1025 string logoFile = null;
1026 string themeFile = null;
1027 string localizationFile = null;
1028 WixManagedBootstrapperApplicationHostTheme? theme = null;
1029
1030 IComponentKeyPath exePayloadRef = null;
1031
1032 foreach (var attrib in node.Attributes())
1033 {
1034 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1035 {
1036 switch (attrib.Name.LocalName)
1037 {
1038 case "AlwaysInstallPrereqs":
1039 alwaysInstallPrereqs = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) == YesNoType.Yes;
1040 break;
1041 case "LogoFile":
1042 logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1043 break;
1044 case "ThemeFile":
1045 themeFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1046 break;
1047 case "LocalizationFile":
1048 localizationFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1049 break;
1050 case "Theme":
1051 var themeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1052 switch (themeValue)
1053 {
1054 case "none":
1055 theme = WixManagedBootstrapperApplicationHostTheme.None;
1056 break;
1057 case "standard":
1058 theme = WixManagedBootstrapperApplicationHostTheme.Standard;
1059 break;
1060 default:
1061 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Theme", themeValue, "none", "standard"));
1062 theme = WixManagedBootstrapperApplicationHostTheme.Unknown;
1063 break;
1064 }
1065 break;
1066 default:
1067 this.ParseHelper.UnexpectedAttribute(node, attrib);
1068 break;
1069 }
1070 }
1071 else
1072 {
1073 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1074 }
1075 }
1076
1077 if (!theme.HasValue)
1078 {
1079 theme = WixManagedBootstrapperApplicationHostTheme.Standard;
1080 }
1081
1082 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
1083
1084 if (!this.Messaging.EncounteredError)
1085 {
1086 if (!String.IsNullOrEmpty(logoFile))
1087 {
1088 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "PreqbaLogo"))
1089 {
1090 Value = logoFile,
1091 });
1092 }
1093
1094 if (!String.IsNullOrEmpty(themeFile))
1095 {
1096 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "PreqbaThemeXml"))
1097 {
1098 Value = themeFile,
1099 });
1100 }
1101
1102 if (!String.IsNullOrEmpty(localizationFile))
1103 {
1104 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "PreqbaThemeWxl"))
1105 {
1106 Value = localizationFile,
1107 });
1108 }
1109
1110 var baId = "WixManagedBootstrapperApplicationHost";
1111 switch (theme)
1112 {
1113 case WixManagedBootstrapperApplicationHostTheme.Standard:
1114 baId = "WixManagedBootstrapperApplicationHost.Standard";
1115 break;
1116 }
1117
1118 exePayloadRef = this.CreatePayloadGroupRef(section, sourceLineNumbers, node, "WixManagedBootstrapperApplicationHost", baId, WixBalBootstrapperApplicationType.ManagedHost);
1119
1120 if (alwaysInstallPrereqs)
1121 {
1122 section.AddSymbol(new WixPrereqOptionsSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixPrereqOptions"))
1123 {
1124 AlwaysInstallPrereqs = 1,
1125 });
1126 }
1127 }
1128
1129 return exePayloadRef;
1130 }
1131
1132 /// <summary>
1133 /// Parses a WixDotNetCoreBootstrapperApplication element for Bundles.
1134 /// </summary>
1135 /// <param name="node">The element to parse.</param>
1136 private IComponentKeyPath ParseWixDotNetCoreBootstrapperApplicationHostElement(Intermediate intermediate, IntermediateSection section, XElement node)
1137 {
1138 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1139 bool alwaysInstallPrereqs = false;
1140 string logoFile = null;
1141 string themeFile = null;
1142 string localizationFile = null;
1143 var selfContainedDeployment = YesNoType.NotSet;
1144 WixDotNetCoreBootstrapperApplicationHostTheme? theme = null;
1145
1146 IComponentKeyPath exePayloadRef = null;
1147
1148 foreach (var attrib in node.Attributes())
1149 {
1150 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1151 {
1152 switch (attrib.Name.LocalName)
1153 {
1154 case "AlwaysInstallPrereqs":
1155 alwaysInstallPrereqs = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) == YesNoType.Yes;
1156 break;
1157 case "LogoFile":
1158 logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1159 break;
1160 case "ThemeFile":
1161 themeFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1162 break;
1163 case "LocalizationFile":
1164 localizationFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1165 break;
1166 case "SelfContainedDeployment":
1167 selfContainedDeployment = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1168 break;
1169 case "Theme":
1170 var themeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1171 switch (themeValue)
1172 {
1173 case "none":
1174 theme = WixDotNetCoreBootstrapperApplicationHostTheme.None;
1175 break;
1176 case "standard":
1177 theme = WixDotNetCoreBootstrapperApplicationHostTheme.Standard;
1178 break;
1179 default:
1180 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Theme", themeValue, "none", "standard"));
1181 theme = WixDotNetCoreBootstrapperApplicationHostTheme.Unknown;
1182 break;
1183 }
1184 break;
1185 default:
1186 this.ParseHelper.UnexpectedAttribute(node, attrib);
1187 break;
1188 }
1189 }
1190 else
1191 {
1192 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1193 }
1194 }
1195
1196 if (!theme.HasValue)
1197 {
1198 theme = WixDotNetCoreBootstrapperApplicationHostTheme.Standard;
1199 }
1200
1201 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
1202
1203 if (!this.Messaging.EncounteredError)
1204 {
1205 if (!String.IsNullOrEmpty(logoFile))
1206 {
1207 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "DncPreqbaLogo"))
1208 {
1209 Value = logoFile,
1210 });
1211 }
1212
1213 if (!String.IsNullOrEmpty(themeFile))
1214 {
1215 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "DncPreqbaThemeXml"))
1216 {
1217 Value = themeFile,
1218 });
1219 }
1220
1221 if (!String.IsNullOrEmpty(localizationFile))
1222 {
1223 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "DncPreqbaThemeWxl"))
1224 {
1225 Value = localizationFile,
1226 });
1227 }
1228
1229 if (YesNoType.Yes == selfContainedDeployment)
1230 {
1231 section.AddSymbol(new WixDncOptionsSymbol(sourceLineNumbers)
1232 {
1233 SelfContainedDeployment = 1,
1234 });
1235 }
1236
1237 var baId = "WixDotNetCoreBootstrapperApplicationHost";
1238 switch (theme)
1239 {
1240 case WixDotNetCoreBootstrapperApplicationHostTheme.Standard:
1241 baId = "WixDotNetCoreBootstrapperApplicationHost.Standard";
1242 break;
1243 }
1244
1245 exePayloadRef = this.CreatePayloadGroupRef(section, sourceLineNumbers, node, "WixDotNetCoreBootstrapperApplicationHost", baId, WixBalBootstrapperApplicationType.DotNetCoreHost);
1246
1247 if (alwaysInstallPrereqs)
1248 {
1249 section.AddSymbol(new WixPrereqOptionsSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixPrereqOptions"))
1250 {
1251 AlwaysInstallPrereqs = 1,
1252 });
1253 }
1254 }
1255
1256 return exePayloadRef;
1257 }
1258 #endif
1259
1260 private string CreatePayloadGroupRef(IntermediateSection section, SourceLineNumber sourceLineNumbers, XElement node, string basePayloadGroupId, bool platformSpecific)
1261 {
1262 var id = platformSpecific ? this.CreateIdentifierFromPlatform(sourceLineNumbers, node, basePayloadGroupId) : basePayloadGroupId;
1263
1264 if (!String.IsNullOrEmpty(id))
1265 {
1266 this.ParseHelper.CreateWixGroupSymbol(section, sourceLineNumbers, ComplexReferenceParentType.Container, BurnConstants.BurnUXContainerName, ComplexReferenceChildType.PayloadGroup, id);
1267
1268 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.WixBundlePayloadGroup, id);
1269 }
1270
1271 return id;
1272 }
1273
1274 private string CreateIdentifierFromPlatform(SourceLineNumber sourceLineNumbers, XElement node, string name)
1275 {
1276 var id = this.ParseHelper.CreateIdentifierValueFromPlatform(name, this.Context.Platform, BurnPlatforms.X86 | BurnPlatforms.X64 | BurnPlatforms.ARM64);
1277 if (id == null)
1278 {
1279 this.Messaging.Write(ErrorMessages.UnsupportedPlatformForElement(sourceLineNumbers, this.Context.Platform.ToString(), node.Name.LocalName));
1280 }
1281
1282 return id;
1283 }
1284 }
1285 }