main
cs 868 lines 41.1 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.Netfx
4 {
5 using System;
6 using System.Collections.Generic;
7 using System.Xml.Linq;
8 using WixToolset.Data;
9 using WixToolset.Extensibility;
10 using WixToolset.Extensibility.Data;
11 using WixToolset.Netfx.Symbols;
12
13 /// <summary>
14 /// The compiler for the WiX Toolset .NET Framework Extension.
15 /// </summary>
16 public sealed class NetfxCompiler : BaseCompilerExtension
17 {
18 public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/netfx";
19
20 /// <summary>
21 /// Processes an element for the Compiler.
22 /// </summary>
23 /// <param name="parentElement">Parent element of element to process.</param>
24 /// <param name="element">Element to process.</param>
25 /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
26 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
27 {
28 switch (parentElement.Name.LocalName)
29 {
30 case "File":
31 string fileId = context["FileId"];
32
33 switch (element.Name.LocalName)
34 {
35 case "NativeImage":
36 this.ParseNativeImageElement(intermediate, section, element, fileId);
37 break;
38 default:
39 this.ParseHelper.UnexpectedElement(parentElement, element);
40 break;
41 }
42 break;
43 case "Fragment":
44 switch (element.Name.LocalName)
45 {
46 case "DotNetCoreSearch":
47 this.ParseDotNetCoreSearchElement(intermediate, section, element);
48 break;
49 case "DotNetCoreSearchRef":
50 this.ParseDotNetCoreSearchRefElement(intermediate, section, element);
51 break;
52 case "DotNetCoreSdkSearch":
53 this.ParseDotNetCoreSdkSearchElement(intermediate, section, element);
54 break;
55 case "DotNetCoreSdkSearchRef":
56 this.ParseDotNetCoreSdkSearchRefElement(intermediate, section, element);
57 break;
58 case "DotNetCoreSdkFeatureBandSearch":
59 this.ParseDotNetCoreSdkFeatureBandSearchElement(intermediate, section, element);
60 break;
61 case "DotNetCoreSdkFeatureBandSearchRef":
62 this.ParseDotNetCoreSdkFeatureBandSearchRefElement(intermediate, section, element);
63 break;
64 case "DotNetCompatibilityCheck":
65 this.ParseDotNetCompatibilityCheckElement(intermediate, section, element);
66 break;
67 case "DotNetCompatibilityCheckRef":
68 this.ParseDotNetCompatibilityCheckRefElement(intermediate, section, element);
69 break;
70 default:
71 this.ParseHelper.UnexpectedElement(parentElement, element);
72 break;
73 }
74 break;
75 case "Bundle":
76 switch (element.Name.LocalName)
77 {
78 case "DotNetCoreSearch":
79 this.ParseDotNetCoreSearchElement(intermediate, section, element);
80 break;
81 case "DotNetCoreSearchRef":
82 this.ParseDotNetCoreSearchRefElement(intermediate, section, element);
83 break;
84 case "DotNetCoreSdkSearch":
85 this.ParseDotNetCoreSdkSearchElement(intermediate, section, element);
86 break;
87 case "DotNetCoreSdkSearchRef":
88 this.ParseDotNetCoreSdkSearchRefElement(intermediate, section, element);
89 break;
90 case "DotNetCoreSdkFeatureBandSearch":
91 this.ParseDotNetCoreSdkFeatureBandSearchElement(intermediate, section, element);
92 break;
93 case "DotNetCoreSdkFeatureBandSearchRef":
94 this.ParseDotNetCoreSdkFeatureBandSearchRefElement(intermediate, section, element);
95 break;
96 default:
97 this.ParseHelper.UnexpectedElement(parentElement, element);
98 break;
99 }
100 break;
101 case "Package":
102 case "Module":
103 switch (element.Name.LocalName)
104 {
105 case "DotNetCompatibilityCheck":
106 this.ParseDotNetCompatibilityCheckElement(intermediate, section, element);
107 break;
108 case "DotNetCompatibilityCheckRef":
109 this.ParseDotNetCompatibilityCheckRefElement(intermediate, section, element);
110 break;
111 default:
112 this.ParseHelper.UnexpectedElement(parentElement, element);
113 break;
114 }
115 break;
116 default:
117 this.ParseHelper.UnexpectedElement(parentElement, element);
118 break;
119 }
120 }
121
122 private void ParseDotNetCoreSearchElement(Intermediate intermediate, IntermediateSection section, XElement element)
123 {
124 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
125 Identifier id = null;
126 string variable = null;
127 string condition = null;
128 string after = null;
129 NetCoreSearchRuntimeType? runtimeType = null;
130 NetCoreSearchPlatform? platform = null;
131 var majorVersion = CompilerConstants.IntegerNotSet;
132
133 foreach (var attrib in element.Attributes())
134 {
135 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
136 {
137 switch (attrib.Name.LocalName)
138 {
139 case "Id":
140 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
141 break;
142 case "Variable":
143 variable = this.ParseHelper.GetAttributeBundleVariableNameValue(sourceLineNumbers, attrib);
144 break;
145 case "Condition":
146 condition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
147 break;
148 case "After":
149 after = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
150 break;
151 case "RuntimeType":
152 var runtimeTypeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
153 switch (runtimeTypeValue)
154 {
155 case "aspnet":
156 runtimeType = NetCoreSearchRuntimeType.Aspnet;
157 break;
158 case "core":
159 runtimeType = NetCoreSearchRuntimeType.Core;
160 break;
161 case "desktop":
162 runtimeType = NetCoreSearchRuntimeType.Desktop;
163 break;
164 default:
165 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "RuntimeType", runtimeTypeValue, "aspnet", "core", "desktop"));
166 break;
167 }
168 break;
169 case "Platform":
170 var platformValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
171 switch (platformValue)
172 {
173 case "arm64":
174 platform = NetCoreSearchPlatform.Arm64;
175 break;
176 case "x64":
177 platform = NetCoreSearchPlatform.X64;
178 break;
179 case "x86":
180 platform = NetCoreSearchPlatform.X86;
181 break;
182 default:
183 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Platform", platformValue, "arm64", "x64", "x86"));
184 break;
185 }
186 break;
187 case "MajorVersion":
188 // .NET Core had a different deployment strategy before .NET Core 3.0 which would require different detection logic.
189 majorVersion = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 3, Int32.MaxValue);
190 break;
191 default:
192 this.ParseHelper.UnexpectedAttribute(element, attrib);
193 break;
194 }
195 }
196 else
197 {
198 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
199 }
200 }
201
202 if (id == null)
203 {
204 id = this.ParseHelper.CreateIdentifier("dncs", variable, condition, after);
205 }
206
207 if (!runtimeType.HasValue)
208 {
209 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "RuntimeType"));
210 }
211
212 if (!platform.HasValue)
213 {
214 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Platform"));
215 }
216
217 if (majorVersion == CompilerConstants.IntegerNotSet)
218 {
219 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "MajorVersion"));
220 }
221 else if (majorVersion == 4)
222 {
223 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "MajorVersion", "4", "3", "5+"));
224 }
225
226 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
227
228 var bootstrapperExtensionId = this.ParseHelper.CreateIdentifierValueFromPlatform("Wix4NetfxBootstrapperExtension", this.Context.Platform, BurnPlatforms.X86 | BurnPlatforms.X64 | BurnPlatforms.ARM64);
229 if (bootstrapperExtensionId == null)
230 {
231 this.Messaging.Write(ErrorMessages.UnsupportedPlatformForElement(sourceLineNumbers, this.Context.Platform.ToString(), element.Name.LocalName));
232 }
233
234 if (!this.Messaging.EncounteredError)
235 {
236 this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, bootstrapperExtensionId);
237
238 section.AddSymbol(new NetFxNetCoreSearchSymbol(sourceLineNumbers, id)
239 {
240 RuntimeType = runtimeType.Value,
241 Platform = platform.Value,
242 MajorVersion = majorVersion,
243 });
244 }
245 }
246
247 private void ParseDotNetCoreSearchRefElement(Intermediate intermediate, IntermediateSection section, XElement element)
248 {
249 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
250
251 foreach (var attrib in element.Attributes())
252 {
253 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
254 {
255 switch (attrib.Name.LocalName)
256 {
257 case "Id":
258 var refId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
259 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, NetfxSymbolDefinitions.NetFxNetCoreSearch, refId);
260 break;
261 default:
262 this.ParseHelper.UnexpectedAttribute(element, attrib);
263 break;
264 }
265 }
266 else
267 {
268 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
269 }
270 }
271
272 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
273 }
274
275 private void ParseDotNetCoreSdkSearchElement(Intermediate intermediate, IntermediateSection section, XElement element)
276 {
277 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
278 Identifier id = null;
279 string variable = null;
280 string condition = null;
281 string after = null;
282 NetCoreSearchPlatform? platform = null;
283 var majorVersion = CompilerConstants.IntegerNotSet;
284
285 foreach (var attrib in element.Attributes())
286 {
287 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
288 {
289 switch (attrib.Name.LocalName)
290 {
291 case "Id":
292 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
293 break;
294 case "Variable":
295 variable = this.ParseHelper.GetAttributeBundleVariableNameValue(sourceLineNumbers, attrib);
296 break;
297 case "Condition":
298 condition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
299 break;
300 case "After":
301 after = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
302 break;
303 case "Platform":
304 var platformValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
305 switch (platformValue)
306 {
307 case "arm64":
308 platform = NetCoreSearchPlatform.Arm64;
309 break;
310 case "x64":
311 platform = NetCoreSearchPlatform.X64;
312 break;
313 case "x86":
314 platform = NetCoreSearchPlatform.X86;
315 break;
316 default:
317 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Platform", platformValue, "arm64", "x64", "x86"));
318 break;
319 }
320 break;
321 case "MajorVersion":
322 // .NET Core had a different deployment strategy before .NET Core 3.0 which would require different detection logic.
323 majorVersion = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 3, Int32.MaxValue);
324 break;
325 default:
326 this.ParseHelper.UnexpectedAttribute(element, attrib);
327 break;
328 }
329 }
330 else
331 {
332 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
333 }
334 }
335
336 if (id == null)
337 {
338 id = this.ParseHelper.CreateIdentifier("dncss", variable, condition, after);
339 }
340
341 if (!platform.HasValue)
342 {
343 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Platform"));
344 }
345
346 if (majorVersion == CompilerConstants.IntegerNotSet)
347 {
348 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "MajorVersion"));
349 }
350 else if (majorVersion == 4)
351 {
352 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "MajorVersion", "4", "3", "5+"));
353 }
354
355 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
356
357 var bootstrapperExtensionId = this.ParseHelper.CreateIdentifierValueFromPlatform("Wix4NetfxBootstrapperExtension", this.Context.Platform, BurnPlatforms.X86 | BurnPlatforms.X64 | BurnPlatforms.ARM64);
358 if (bootstrapperExtensionId == null)
359 {
360 this.Messaging.Write(ErrorMessages.UnsupportedPlatformForElement(sourceLineNumbers, this.Context.Platform.ToString(), element.Name.LocalName));
361 }
362
363 if (!this.Messaging.EncounteredError)
364 {
365 this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, bootstrapperExtensionId);
366
367 section.AddSymbol(new NetFxNetCoreSdkSearchSymbol(sourceLineNumbers, id)
368 {
369 Platform = platform.Value,
370 MajorVersion = majorVersion,
371 });
372 }
373 }
374
375 private void ParseDotNetCoreSdkSearchRefElement(Intermediate intermediate, IntermediateSection section, XElement element)
376 {
377 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
378
379 foreach (var attrib in element.Attributes())
380 {
381 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
382 {
383 switch (attrib.Name.LocalName)
384 {
385 case "Id":
386 var refId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
387 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, NetfxSymbolDefinitions.NetFxNetCoreSdkSearch, refId);
388 break;
389 default:
390 this.ParseHelper.UnexpectedAttribute(element, attrib);
391 break;
392 }
393 }
394 else
395 {
396 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
397 }
398 }
399
400 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
401 }
402
403 private void ParseDotNetCoreSdkFeatureBandSearchElement(Intermediate intermediate, IntermediateSection section, XElement element)
404 {
405 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
406 Identifier id = null;
407 string variable = null;
408 string condition = null;
409 string after = null;
410 NetCoreSearchPlatform? platform = null;
411 string version = null;
412 var majorVersion = 0;
413 var minorVersion = 0;
414 var patchVersion = 0;
415
416 foreach (var attrib in element.Attributes())
417 {
418 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
419 {
420 switch (attrib.Name.LocalName)
421 {
422 case "Id":
423 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
424 break;
425 case "Variable":
426 variable = this.ParseHelper.GetAttributeBundleVariableNameValue(sourceLineNumbers, attrib);
427 break;
428 case "Condition":
429 condition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
430 break;
431 case "After":
432 after = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
433 break;
434 case "Platform":
435 var platformValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
436 switch (platformValue)
437 {
438 case "arm64":
439 platform = NetCoreSearchPlatform.Arm64;
440 break;
441 case "x64":
442 platform = NetCoreSearchPlatform.X64;
443 break;
444 case "x86":
445 platform = NetCoreSearchPlatform.X86;
446 break;
447 default:
448 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Platform", platformValue, "arm64", "x64", "x86"));
449 break;
450 }
451 break;
452 case "Version":
453 version = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
454 break;
455 default:
456 this.ParseHelper.UnexpectedAttribute(element, attrib);
457 break;
458 }
459 }
460 else
461 {
462 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
463 }
464 }
465
466 if (id == null)
467 {
468 id = this.ParseHelper.CreateIdentifier("dncsfbs", variable, condition, after);
469 }
470
471 if (!platform.HasValue)
472 {
473 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Platform"));
474 }
475
476 if (String.IsNullOrEmpty(version))
477 {
478 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Version"));
479 }
480 else
481 {
482 if (!Version.TryParse(version, out var featureBandVersion))
483 {
484 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Version", version, "x.x.x00"));
485 }
486 else
487 {
488 majorVersion = featureBandVersion.Major;
489 minorVersion = featureBandVersion.Minor;
490 patchVersion = featureBandVersion.Build;
491
492 if ((patchVersion % 100) != 0 || featureBandVersion.Revision != -1)
493 {
494 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Version", version, "x.x.x00"));
495 }
496
497 if (majorVersion == 4)
498 {
499 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Version", version, "3.*", "5+.*"));
500 }
501 }
502 }
503
504 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
505
506 var bootstrapperExtensionId = this.ParseHelper.CreateIdentifierValueFromPlatform("Wix4NetfxBootstrapperExtension", this.Context.Platform, BurnPlatforms.X86 | BurnPlatforms.X64 | BurnPlatforms.ARM64);
507 if (bootstrapperExtensionId == null)
508 {
509 this.Messaging.Write(ErrorMessages.UnsupportedPlatformForElement(sourceLineNumbers, this.Context.Platform.ToString(), element.Name.LocalName));
510 }
511
512 if (!this.Messaging.EncounteredError)
513 {
514 this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, bootstrapperExtensionId);
515
516 section.AddSymbol(new NetFxNetCoreSdkFeatureBandSearchSymbol(sourceLineNumbers, id)
517 {
518 Platform = platform.Value,
519 MajorVersion = majorVersion,
520 MinorVersion = minorVersion,
521 PatchVersion = patchVersion,
522 });
523 }
524 }
525
526 private void ParseDotNetCoreSdkFeatureBandSearchRefElement(Intermediate intermediate, IntermediateSection section, XElement element)
527 {
528 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
529
530 foreach (var attrib in element.Attributes())
531 {
532 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
533 {
534 switch (attrib.Name.LocalName)
535 {
536 case "Id":
537 var refId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
538 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, NetfxSymbolDefinitions.NetFxNetCoreSdkFeatureBandSearch, refId);
539 break;
540 default:
541 this.ParseHelper.UnexpectedAttribute(element, attrib);
542 break;
543 }
544 }
545 else
546 {
547 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
548 }
549 }
550
551 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
552 }
553
554 /// <summary>
555 /// Parses a NativeImage element.
556 /// </summary>
557 /// <param name="element">The element to parse.</param>
558 /// <param name="fileId">The file identifier of the parent element.</param>
559 private void ParseNativeImageElement(Intermediate intermediate, IntermediateSection section, XElement element, string fileId)
560 {
561 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
562 Identifier id = null;
563 string appBaseDirectory = null;
564 string assemblyApplication = null;
565 int attributes = 0x8; // 32bit is on by default
566 int priority = 3;
567
568 foreach (var attrib in element.Attributes())
569 {
570 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
571 {
572 switch (attrib.Name.LocalName)
573 {
574 case "Id":
575 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
576 break;
577 case "AppBaseDirectory":
578 appBaseDirectory = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
579
580 // See if a formatted value is specified.
581 if (-1 == appBaseDirectory.IndexOf("[", StringComparison.Ordinal))
582 {
583 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Directory, appBaseDirectory);
584 }
585 break;
586 case "AssemblyApplication":
587 assemblyApplication = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
588
589 // See if a formatted value is specified.
590 if (-1 == assemblyApplication.IndexOf("[", StringComparison.Ordinal))
591 {
592 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.File, assemblyApplication);
593 }
594 break;
595 case "Debug":
596 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
597 {
598 attributes |= 0x1;
599 }
600 break;
601 case "Dependencies":
602 if (YesNoType.No == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
603 {
604 attributes |= 0x2;
605 }
606 break;
607 case "Platform":
608 string platformValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
609 if (0 < platformValue.Length)
610 {
611 switch (platformValue)
612 {
613 case "32bit":
614 // 0x8 is already on by default
615 break;
616 case "64bit":
617 attributes &= ~0x8;
618 attributes |= 0x10;
619 break;
620 case "all":
621 attributes |= 0x10;
622 break;
623 }
624 }
625 break;
626 case "Priority":
627 priority = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 3);
628 break;
629 case "Profile":
630 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
631 {
632 attributes |= 0x4;
633 }
634 break;
635 default:
636 this.ParseHelper.UnexpectedAttribute(element, attrib);
637 break;
638 }
639 }
640 else
641 {
642 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
643 }
644 }
645
646 if (null == id)
647 {
648 id = this.ParseHelper.CreateIdentifier("nni", fileId);
649 }
650
651 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
652
653 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4NetFxScheduleNativeImage", this.Context.Platform, CustomActionPlatforms.ARM64 | CustomActionPlatforms.X64 | CustomActionPlatforms.X86);
654
655 if (!this.Messaging.EncounteredError)
656 {
657 section.AddSymbol(new NetFxNativeImageSymbol(sourceLineNumbers, id)
658 {
659 FileRef = fileId,
660 Priority = priority,
661 Attributes = attributes,
662 ApplicationFileRef = assemblyApplication,
663 ApplicationBaseDirectoryRef = appBaseDirectory,
664 });
665 }
666 }
667
668 /// <summary>
669 /// Parses a DotNetCompatibilityCheck element.
670 /// </summary>
671 /// <param name="element">The element to parse.</param>
672 private void ParseDotNetCompatibilityCheckElement(Intermediate intermediate, IntermediateSection section, XElement element)
673 {
674 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
675 Identifier id = null;
676 string property = null;
677 string runtimeType = null;
678 string platform = null;
679 string version = null;
680 string rollForward = "Minor";
681
682 foreach (var attrib in element.Attributes())
683 {
684 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
685 {
686 switch (attrib.Name.LocalName)
687 {
688 case "Id":
689 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
690 break;
691 case "Property":
692 property = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
693 break;
694 case "RuntimeType":
695 runtimeType = this.ParseRuntimeType(element, sourceLineNumbers, attrib);
696 break;
697 case "Platform":
698 platform = this.ParsePlatform(element, sourceLineNumbers, attrib);
699 break;
700 case "Version":
701 version = this.ParseHelper.GetAttributeVersionValue(sourceLineNumbers, attrib);
702 break;
703 case "RollForward":
704 rollForward = this.ParseRollForward(element, sourceLineNumbers, attrib);
705 break;
706 default:
707 this.ParseHelper.UnexpectedAttribute(element, attrib);
708 break;
709 }
710 }
711 else
712 {
713 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
714 }
715 }
716
717 if (null == id)
718 {
719 id = this.ParseHelper.CreateIdentifier("ndncc", property, runtimeType, platform, version);
720 }
721
722 if (String.IsNullOrEmpty(property))
723 {
724 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Property"));
725 }
726
727 if (String.IsNullOrEmpty(runtimeType))
728 {
729 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "RuntimeType"));
730 }
731
732 if (String.IsNullOrEmpty(platform))
733 {
734 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Platform"));
735 }
736
737 if (String.IsNullOrEmpty(version))
738 {
739 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Version"));
740 }
741
742 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
743
744 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4NetFxDotNetCompatibilityCheck", this.Context.Platform, CustomActionPlatforms.ARM64 | CustomActionPlatforms.X64 | CustomActionPlatforms.X86);
745
746 if (!this.Messaging.EncounteredError)
747 {
748 section.AddSymbol(new NetFxDotNetCompatibilityCheckSymbol(sourceLineNumbers, id)
749 {
750 RuntimeType = runtimeType,
751 Platform = platform,
752 Version = version,
753 RollForward = rollForward,
754 Property = property,
755 });
756 }
757 }
758
759 private string ParseRollForward(XElement element, SourceLineNumber sourceLineNumbers, XAttribute attrib)
760 {
761 string rollForward;
762 rollForward = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
763 switch (rollForward.ToLowerInvariant())
764 {
765 case "latestmajor":
766 rollForward = "LatestMajor";
767 break;
768 case "major":
769 rollForward = "Major";
770 break;
771 case "latestminor":
772 rollForward = "LatestMinor";
773 break;
774 case "minor":
775 rollForward = "Minor";
776 break;
777 case "latestpatch":
778 rollForward = "LatestPatch";
779 break;
780 case "disable":
781 rollForward = "Disable";
782 break;
783 default:
784 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName,
785 attrib.Name.LocalName, rollForward, "latestmajor", "major", "latestminor", "minor", "latestpatch", "disable"));
786 break;
787 }
788
789 return rollForward;
790 }
791
792 private string ParsePlatform(XElement element, SourceLineNumber sourceLineNumbers, XAttribute attrib)
793 {
794 string platform;
795 platform = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
796 switch (platform.ToLower())
797 {
798 case "x86":
799 case "x64":
800 case "arm64":
801 platform = platform.ToLower();
802 break;
803 default:
804 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName,
805 attrib.Name.LocalName, platform, "x86", "x64", "arm64"));
806 break;
807 }
808
809 return platform;
810 }
811
812 private string ParseRuntimeType(XElement element, SourceLineNumber sourceLineNumbers, XAttribute attrib)
813 {
814 var runtimeType = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
815 switch (runtimeType.ToLower())
816 {
817 case "aspnet":
818 runtimeType = "Microsoft.AspNetCore.App";
819 break;
820 case "desktop":
821 runtimeType = "Microsoft.WindowsDesktop.App";
822 break;
823 case "core":
824 runtimeType = "Microsoft.NETCore.App";
825 break;
826 default:
827 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName,
828 attrib.Name.LocalName, runtimeType, "aspnet", "desktop", "core"));
829 break;
830 }
831
832 return runtimeType;
833 }
834
835
836 /// <summary>
837 /// Parses a DotNetCompatibilityCheckRef element.
838 /// </summary>
839 /// <param name="element">The element to parse.</param>
840 private void ParseDotNetCompatibilityCheckRefElement(Intermediate intermediate, IntermediateSection section, XElement element)
841 {
842 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
843
844 foreach (var attrib in element.Attributes())
845 {
846 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
847 {
848 switch (attrib.Name.LocalName)
849 {
850 case "Id":
851 var refId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
852 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, NetfxSymbolDefinitions.NetFxDotNetCompatibilityCheck, refId);
853 break;
854 default:
855 this.ParseHelper.UnexpectedAttribute(element, attrib);
856 break;
857 }
858 }
859 else
860 {
861 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
862 }
863 }
864
865 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
866 }
867 }
868 }