aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/ExtensibilityServices
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core/ExtensibilityServices')
-rw-r--r--src/WixToolset.Core/ExtensibilityServices/ExtensionManager.cs113
-rw-r--r--src/WixToolset.Core/ExtensibilityServices/Messaging.cs194
-rw-r--r--src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs66
-rw-r--r--src/WixToolset.Core/ExtensibilityServices/PreprocessHelper.cs38
4 files changed, 361 insertions, 50 deletions
diff --git a/src/WixToolset.Core/ExtensibilityServices/ExtensionManager.cs b/src/WixToolset.Core/ExtensibilityServices/ExtensionManager.cs
new file mode 100644
index 00000000..5714701a
--- /dev/null
+++ b/src/WixToolset.Core/ExtensibilityServices/ExtensionManager.cs
@@ -0,0 +1,113 @@
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.Core.ExtensibilityServices
4{
5 using System;
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Linq;
9 using System.Reflection;
10 using WixToolset.Data;
11 using WixToolset.Extensibility;
12 using WixToolset.Extensibility.Services;
13
14 internal class ExtensionManager : IExtensionManager
15 {
16 private List<IExtensionFactory> extensionFactories = new List<IExtensionFactory>();
17 private Dictionary<Type, List<object>> loadedExtensionsByType = new Dictionary<Type, List<object>>();
18
19 public void Add(Assembly extensionAssembly)
20 {
21 var types = extensionAssembly.GetTypes().Where(t => !t.IsAbstract && !t.IsInterface && typeof(IExtensionFactory).IsAssignableFrom(t));
22 var factories = types.Select(t => (IExtensionFactory)Activator.CreateInstance(t)).ToList();
23
24 this.extensionFactories.AddRange(factories);
25 }
26
27 public void Load(string extensionPath)
28 {
29 Assembly assembly;
30
31 // Absolute path to an assembly which means only "load from" will work even though we'd prefer to
32 // use Assembly.Load (see the documentation for Assembly.LoadFrom why).
33 if (Path.IsPathRooted(extensionPath))
34 {
35 assembly = ExtensionManager.ExtensionLoadFrom(extensionPath);
36 }
37 else if (ExtensionManager.TryExtensionLoad(extensionPath, out assembly))
38 {
39 // Loaded the assembly by name from the probing path.
40 }
41 else if (ExtensionManager.TryExtensionLoad(Path.GetFileNameWithoutExtension(extensionPath), out assembly))
42 {
43 // Loaded the assembly by filename alone along the probing path.
44 }
45 else // relative path to an assembly
46 {
47 // We want to use Assembly.Load when we can because it has some benefits over Assembly.LoadFrom
48 // (see the documentation for Assembly.LoadFrom). However, it may fail when the path is a relative
49 // path, so we should try Assembly.LoadFrom one last time. We could have detected a directory
50 // separator character and used Assembly.LoadFrom directly, but dealing with path canonicalization
51 // issues is something we don't want to deal with if we don't have to.
52 assembly = ExtensionManager.ExtensionLoadFrom(extensionPath);
53 }
54
55 this.Add(assembly);
56 }
57
58 public IEnumerable<T> Create<T>() where T : class
59 {
60 if (!this.loadedExtensionsByType.TryGetValue(typeof(T), out var extensions))
61 {
62 extensions = new List<object>();
63
64 foreach (var factory in this.extensionFactories)
65 {
66 if (factory.TryCreateExtension(typeof(T), out var obj) && obj is T extension)
67 {
68 extensions.Add(extension);
69 }
70 }
71
72 this.loadedExtensionsByType.Add(typeof(T), extensions);
73 }
74
75 return extensions.Cast<T>().ToList();
76 }
77
78 private static Assembly ExtensionLoadFrom(string assemblyName)
79 {
80 try
81 {
82 return Assembly.LoadFrom(assemblyName);
83 }
84 catch (Exception e)
85 {
86 throw new WixException(ErrorMessages.InvalidExtension(assemblyName, e.Message), e);
87 }
88 }
89
90 private static bool TryExtensionLoad(string assemblyName, out Assembly assembly)
91 {
92 try
93 {
94 assembly = Assembly.Load(assemblyName);
95 return true;
96 }
97 catch (IOException innerE)
98 {
99 if (innerE is FileLoadException || innerE is FileNotFoundException)
100 {
101 assembly = null;
102 return false;
103 }
104
105 throw new WixException(ErrorMessages.InvalidExtension(assemblyName, innerE.Message), innerE);
106 }
107 catch (Exception e)
108 {
109 throw new WixException(ErrorMessages.InvalidExtension(assemblyName, e.Message), e);
110 }
111 }
112 }
113}
diff --git a/src/WixToolset.Core/ExtensibilityServices/Messaging.cs b/src/WixToolset.Core/ExtensibilityServices/Messaging.cs
new file mode 100644
index 00000000..4510f264
--- /dev/null
+++ b/src/WixToolset.Core/ExtensibilityServices/Messaging.cs
@@ -0,0 +1,194 @@
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.Core.ExtensibilityServices
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Globalization;
8 using System.Text;
9 using WixToolset.Data;
10 using WixToolset.Extensibility;
11 using WixToolset.Extensibility.Services;
12
13 internal class Messaging : IMessaging
14 {
15 private IMessageListener listener;
16 private HashSet<int> suppressedWarnings = new HashSet<int>();
17 private HashSet<int> warningsAsErrors = new HashSet<int>();
18
19 public bool EncounteredError { get; private set; }
20
21 public int LastErrorNumber { get; private set; }
22
23 public bool ShowVerboseMessages { get; set; }
24
25 public bool SuppressAllWarnings { get; set; }
26
27 public bool WarningsAsError { get; set; }
28
29 public void ElevateWarningMessage(int warningNumber)
30 {
31 this.warningsAsErrors.Add(warningNumber);
32 }
33
34 public void SetListener(IMessageListener listener)
35 {
36 this.listener = listener;
37 }
38
39 public void SuppressWarningMessage(int warningNumber)
40 {
41 this.suppressedWarnings.Add(warningNumber);
42 }
43
44 public string FormatMessage(Message message)
45 {
46 var level = CalculateMessageLevel(message);
47
48 if (level == MessageLevel.Nothing)
49 {
50 return String.Empty;
51 }
52
53 var shortAppName = String.IsNullOrEmpty(this.listener?.ShortAppName) ? "WIX" : this.listener.ShortAppName;
54 var longAppName = String.IsNullOrEmpty(this.listener?.LongAppName) ? "WIX" : this.listener.LongAppName;
55
56 var fileNames = new List<string>();
57 var errorFileName = longAppName;
58 for (var sln = message.SourceLineNumbers; null != sln; sln = sln.Parent)
59 {
60 if (String.IsNullOrEmpty(sln.FileName))
61 {
62 continue;
63 }
64 else if (sln.LineNumber.HasValue)
65 {
66 if (fileNames.Count == 0)
67 {
68 errorFileName = String.Format(CultureInfo.CurrentUICulture, WixStrings.Format_FirstLineNumber, sln.FileName, sln.LineNumber);
69 }
70
71 fileNames.Add(String.Format(CultureInfo.CurrentUICulture, WixStrings.Format_LineNumber, sln.FileName, sln.LineNumber));
72 }
73 else
74 {
75 if (fileNames.Count == 0)
76 {
77 errorFileName = sln.FileName;
78 }
79
80 fileNames.Add(sln.FileName);
81 }
82 }
83
84 var levelString = String.Empty;
85 if (MessageLevel.Warning == level)
86 {
87 levelString = WixStrings.MessageType_Warning;
88 }
89 else if (MessageLevel.Error == level)
90 {
91 levelString = WixStrings.MessageType_Error;
92 }
93
94 string formatted;
95 if (message.ResourceManager == null)
96 {
97 formatted = String.Format(CultureInfo.InvariantCulture, message.ResourceNameOrFormat, message.MessageArgs);
98 }
99 else
100 {
101 formatted = String.Format(CultureInfo.InvariantCulture, message.ResourceManager.GetString(message.ResourceNameOrFormat), message.MessageArgs);
102 }
103
104 var builder = new StringBuilder();
105 if (level == MessageLevel.Information || level == MessageLevel.Verbose)
106 {
107 builder.AppendFormat(WixStrings.Format_InfoMessage, formatted);
108 }
109 else
110 {
111 builder.AppendFormat(WixStrings.Format_NonInfoMessage, errorFileName, levelString, shortAppName, message.Id, formatted);
112 }
113
114 if (fileNames.Count > 1)
115 {
116 builder.AppendFormat(WixStrings.INF_SourceTrace, Environment.NewLine);
117
118 foreach (var fileName in fileNames)
119 {
120 builder.AppendFormat(WixStrings.INF_SourceTraceLocation, fileName, Environment.NewLine);
121 }
122
123 builder.AppendLine();
124 }
125
126 return builder.ToString();
127 }
128
129 public void Write(Message message)
130 {
131 var level = CalculateMessageLevel(message);
132
133 if (level == MessageLevel.Nothing)
134 {
135 return;
136 }
137
138 if (level == MessageLevel.Error)
139 {
140 this.EncounteredError = true;
141 this.LastErrorNumber = message.Id;
142 }
143
144 if (this.listener != null)
145 {
146 this.listener.Write(message);
147 }
148 else if (level == MessageLevel.Error)
149 {
150 throw new WixException(message);
151 }
152 }
153
154 public void Write(string message, bool verbose = false)
155 {
156 if (!verbose || this.ShowVerboseMessages)
157 {
158 this.listener?.Write(message);
159 }
160 }
161
162 /// <summary>
163 /// Determines the level of this message, when taking into account warning-as-error,
164 /// warning level, verbosity level and message suppressed by the caller.
165 /// </summary>
166 /// <param name="message">Event arguments for the message.</param>
167 /// <returns>MessageLevel representing the level of this message.</returns>
168 private MessageLevel CalculateMessageLevel(Message message)
169 {
170 var level = message.Level;
171
172 if (level == MessageLevel.Verbose)
173 {
174 if (!this.ShowVerboseMessages)
175 {
176 level = MessageLevel.Nothing;
177 }
178 }
179 else if (level == MessageLevel.Warning)
180 {
181 if (this.SuppressAllWarnings || this.suppressedWarnings.Contains(message.Id))
182 {
183 level = MessageLevel.Nothing;
184 }
185 else if (this.WarningsAsError || this.warningsAsErrors.Contains(message.Id))
186 {
187 level = MessageLevel.Error;
188 }
189 }
190
191 return level;
192 }
193 }
194}
diff --git a/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs b/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
index 8a67efe9..d2486890 100644
--- a/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
+++ b/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
@@ -34,10 +34,14 @@ namespace WixToolset.Core.ExtensibilityServices
34 public ParseHelper(IServiceProvider serviceProvider) 34 public ParseHelper(IServiceProvider serviceProvider)
35 { 35 {
36 this.ServiceProvider = serviceProvider; 36 this.ServiceProvider = serviceProvider;
37
38 this.Messaging = serviceProvider.GetService<IMessaging>();
37 } 39 }
38 40
39 private IServiceProvider ServiceProvider { get; } 41 private IServiceProvider ServiceProvider { get; }
40 42
43 private IMessaging Messaging { get; }
44
41 private ITupleDefinitionCreator Creator { get; set; } 45 private ITupleDefinitionCreator Creator { get; set; }
42 46
43 public bool ContainsProperty(string possibleProperty) 47 public bool ContainsProperty(string possibleProperty)
@@ -136,7 +140,7 @@ namespace WixToolset.Core.ExtensibilityServices
136 // TODO: should overriding the parent identifier with a specific id be an error or a warning or just let it slide? 140 // TODO: should overriding the parent identifier with a specific id be an error or a warning or just let it slide?
137 //if (null != parentId) 141 //if (null != parentId)
138 //{ 142 //{
139 // this.core.OnMessage(WixErrors.Xxx(sourceLineNumbers)); 143 // this.core.Write(WixErrors.Xxx(sourceLineNumbers));
140 //} 144 //}
141 145
142 id = inlineSyntax[0].TrimEnd(':'); 146 id = inlineSyntax[0].TrimEnd(':');
@@ -360,7 +364,7 @@ namespace WixToolset.Core.ExtensibilityServices
360 364
361 if (ParseHelper.PutGuidHere.IsMatch(value)) 365 if (ParseHelper.PutGuidHere.IsMatch(value))
362 { 366 {
363 Messaging.Instance.OnMessage(WixErrors.ExampleGuid(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); 367 this.Messaging.Write(ErrorMessages.ExampleGuid(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
364 return CompilerConstants.IllegalGuid; 368 return CompilerConstants.IllegalGuid;
365 } 369 }
366 else if (value.StartsWith("!(loc", StringComparison.Ordinal) || value.StartsWith("$(loc", StringComparison.Ordinal) || value.StartsWith("!(wix", StringComparison.Ordinal)) 370 else if (value.StartsWith("!(loc", StringComparison.Ordinal) || value.StartsWith("$(loc", StringComparison.Ordinal) || value.StartsWith("!(wix", StringComparison.Ordinal))
@@ -374,14 +378,14 @@ namespace WixToolset.Core.ExtensibilityServices
374 // TODO: This used to be a pedantic error, what should it be now? 378 // TODO: This used to be a pedantic error, what should it be now?
375 //if (uppercaseGuid != value) 379 //if (uppercaseGuid != value)
376 //{ 380 //{
377 // Messaging.Instance.OnMessage(WixErrors.GuidContainsLowercaseLetters(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); 381 // this.Messaging.Write(WixErrors.GuidContainsLowercaseLetters(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
378 //} 382 //}
379 383
380 return String.Concat("{", uppercaseGuid, "}"); 384 return String.Concat("{", uppercaseGuid, "}");
381 } 385 }
382 else 386 else
383 { 387 {
384 Messaging.Instance.OnMessage(WixErrors.IllegalGuidValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); 388 this.Messaging.Write(ErrorMessages.IllegalGuidValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
385 } 389 }
386 } 390 }
387 391
@@ -391,7 +395,7 @@ namespace WixToolset.Core.ExtensibilityServices
391 public Identifier GetAttributeIdentifier(SourceLineNumber sourceLineNumbers, XAttribute attribute) 395 public Identifier GetAttributeIdentifier(SourceLineNumber sourceLineNumbers, XAttribute attribute)
392 { 396 {
393 var access = AccessModifier.Public; 397 var access = AccessModifier.Public;
394 var value = Common.GetAttributeValue(sourceLineNumbers, attribute, EmptyRule.CanBeEmpty); 398 var value = Common.GetAttributeValue(this.Messaging, sourceLineNumbers, attribute, EmptyRule.CanBeEmpty);
395 399
396 var match = ParseHelper.LegalIdentifierWithAccess.Match(value); 400 var match = ParseHelper.LegalIdentifierWithAccess.Match(value);
397 if (!match.Success) 401 if (!match.Success)
@@ -407,7 +411,7 @@ namespace WixToolset.Core.ExtensibilityServices
407 411
408 if (Common.IsIdentifier(value) && 72 < value.Length) 412 if (Common.IsIdentifier(value) && 72 < value.Length)
409 { 413 {
410 Messaging.Instance.OnMessage(WixWarnings.IdentifierTooLong(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); 414 this.Messaging.Write(WarningMessages.IdentifierTooLong(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
411 } 415 }
412 416
413 return new Identifier(value, access); 417 return new Identifier(value, access);
@@ -415,7 +419,7 @@ namespace WixToolset.Core.ExtensibilityServices
415 419
416 public string GetAttributeIdentifierValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) 420 public string GetAttributeIdentifierValue(SourceLineNumber sourceLineNumbers, XAttribute attribute)
417 { 421 {
418 return Common.GetAttributeIdentifierValue(sourceLineNumbers, attribute); 422 return Common.GetAttributeIdentifierValue(this.Messaging, sourceLineNumbers, attribute);
419 } 423 }
420 424
421 public string[] GetAttributeInlineDirectorySyntax(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool resultUsedToCreateReference = false) 425 public string[] GetAttributeInlineDirectorySyntax(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool resultUsedToCreateReference = false)
@@ -432,12 +436,12 @@ namespace WixToolset.Core.ExtensibilityServices
432 string id = result[0].TrimEnd(':'); 436 string id = result[0].TrimEnd(':');
433 if (1 == result.Length) 437 if (1 == result.Length)
434 { 438 {
435 Messaging.Instance.OnMessage(WixErrors.InlineDirectorySyntaxRequiresPath(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, id)); 439 this.Messaging.Write(ErrorMessages.InlineDirectorySyntaxRequiresPath(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, id));
436 return null; 440 return null;
437 } 441 }
438 else if (!this.IsValidIdentifier(id)) 442 else if (!this.IsValidIdentifier(id))
439 { 443 {
440 Messaging.Instance.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, id)); 444 this.Messaging.Write(ErrorMessages.IllegalIdentifier(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, id));
441 return null; 445 return null;
442 } 446 }
443 447
@@ -449,13 +453,13 @@ namespace WixToolset.Core.ExtensibilityServices
449 { 453 {
450 if (!this.IsValidLongFilename(result[0], false, false)) 454 if (!this.IsValidLongFilename(result[0], false, false))
451 { 455 {
452 Messaging.Instance.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, result[0])); 456 this.Messaging.Write(ErrorMessages.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, result[0]));
453 return null; 457 return null;
454 } 458 }
455 } 459 }
456 else if (!this.IsValidIdentifier(result[0])) 460 else if (!this.IsValidIdentifier(result[0]))
457 { 461 {
458 Messaging.Instance.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, result[0])); 462 this.Messaging.Write(ErrorMessages.IllegalIdentifier(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, result[0]));
459 return null; 463 return null;
460 } 464 }
461 465
@@ -467,14 +471,14 @@ namespace WixToolset.Core.ExtensibilityServices
467 { 471 {
468 if (!this.IsValidLongFilename(result[i], false, false)) 472 if (!this.IsValidLongFilename(result[i], false, false))
469 { 473 {
470 Messaging.Instance.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, result[i])); 474 this.Messaging.Write(ErrorMessages.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, result[i]));
471 return null; 475 return null;
472 } 476 }
473 } 477 }
474 478
475 if (1 < result.Length && !value.EndsWith("\\")) 479 if (1 < result.Length && !value.EndsWith("\\"))
476 { 480 {
477 Messaging.Instance.OnMessage(WixWarnings.BackslashTerminateInlineDirectorySyntax(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); 481 this.Messaging.Write(WarningMessages.BackslashTerminateInlineDirectorySyntax(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
478 } 482 }
479 } 483 }
480 484
@@ -483,7 +487,7 @@ namespace WixToolset.Core.ExtensibilityServices
483 487
484 public int GetAttributeIntegerValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, int minimum, int maximum) 488 public int GetAttributeIntegerValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, int minimum, int maximum)
485 { 489 {
486 return Common.GetAttributeIntegerValue(sourceLineNumbers, attribute, minimum, maximum); 490 return Common.GetAttributeIntegerValue(this.Messaging, sourceLineNumbers, attribute, minimum, maximum);
487 } 491 }
488 492
489 public string GetAttributeLongFilename(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool allowWildcards, bool allowRelative) 493 public string GetAttributeLongFilename(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool allowWildcards, bool allowRelative)
@@ -501,11 +505,11 @@ namespace WixToolset.Core.ExtensibilityServices
501 { 505 {
502 if (allowRelative) 506 if (allowRelative)
503 { 507 {
504 Messaging.Instance.OnMessage(WixErrors.IllegalRelativeLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); 508 this.Messaging.Write(ErrorMessages.IllegalRelativeLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
505 } 509 }
506 else 510 else
507 { 511 {
508 Messaging.Instance.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); 512 this.Messaging.Write(ErrorMessages.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
509 } 513 }
510 } 514 }
511 else if (allowRelative) 515 else if (allowRelative)
@@ -513,12 +517,12 @@ namespace WixToolset.Core.ExtensibilityServices
513 string normalizedPath = value.Replace('\\', '/'); 517 string normalizedPath = value.Replace('\\', '/');
514 if (normalizedPath.StartsWith("../", StringComparison.Ordinal) || normalizedPath.Contains("/../")) 518 if (normalizedPath.StartsWith("../", StringComparison.Ordinal) || normalizedPath.Contains("/../"))
515 { 519 {
516 Messaging.Instance.OnMessage(WixErrors.PayloadMustBeRelativeToCache(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); 520 this.Messaging.Write(ErrorMessages.PayloadMustBeRelativeToCache(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
517 } 521 }
518 } 522 }
519 else if (CompilerCore.IsAmbiguousFilename(value)) 523 else if (CompilerCore.IsAmbiguousFilename(value))
520 { 524 {
521 Messaging.Instance.OnMessage(WixWarnings.AmbiguousFileOrDirectoryName(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); 525 this.Messaging.Write(WarningMessages.AmbiguousFileOrDirectoryName(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
522 } 526 }
523 } 527 }
524 528
@@ -539,11 +543,11 @@ namespace WixToolset.Core.ExtensibilityServices
539 543
540 if (CompilerConstants.LongNotSet == longValue || CompilerConstants.IllegalLong == longValue) 544 if (CompilerConstants.LongNotSet == longValue || CompilerConstants.IllegalLong == longValue)
541 { 545 {
542 Messaging.Instance.OnMessage(WixErrors.IntegralValueSentinelCollision(sourceLineNumbers, longValue)); 546 this.Messaging.Write(ErrorMessages.IntegralValueSentinelCollision(sourceLineNumbers, longValue));
543 } 547 }
544 else if (minimum > longValue || maximum < longValue) 548 else if (minimum > longValue || maximum < longValue)
545 { 549 {
546 Messaging.Instance.OnMessage(WixErrors.IntegralValueOutOfRange(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, longValue, minimum, maximum)); 550 this.Messaging.Write(ErrorMessages.IntegralValueOutOfRange(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, longValue, minimum, maximum));
547 longValue = CompilerConstants.IllegalLong; 551 longValue = CompilerConstants.IllegalLong;
548 } 552 }
549 553
@@ -551,11 +555,11 @@ namespace WixToolset.Core.ExtensibilityServices
551 } 555 }
552 catch (FormatException) 556 catch (FormatException)
553 { 557 {
554 Messaging.Instance.OnMessage(WixErrors.IllegalLongValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); 558 this.Messaging.Write(ErrorMessages.IllegalLongValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
555 } 559 }
556 catch (OverflowException) 560 catch (OverflowException)
557 { 561 {
558 Messaging.Instance.OnMessage(WixErrors.IllegalLongValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); 562 this.Messaging.Write(ErrorMessages.IllegalLongValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
559 } 563 }
560 } 564 }
561 565
@@ -564,7 +568,7 @@ namespace WixToolset.Core.ExtensibilityServices
564 568
565 public string GetAttributeValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, EmptyRule emptyRule = EmptyRule.CanBeWhitespaceOnly) 569 public string GetAttributeValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, EmptyRule emptyRule = EmptyRule.CanBeWhitespaceOnly)
566 { 570 {
567 return Common.GetAttributeValue(sourceLineNumbers, attribute, emptyRule); 571 return Common.GetAttributeValue(this.Messaging, sourceLineNumbers, attribute, emptyRule);
568 } 572 }
569 573
570 public string GetAttributeVersionValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) 574 public string GetAttributeVersionValue(SourceLineNumber sourceLineNumbers, XAttribute attribute)
@@ -584,7 +588,7 @@ namespace WixToolset.Core.ExtensibilityServices
584 return value; 588 return value;
585 } 589 }
586 590
587 Messaging.Instance.OnMessage(WixErrors.IllegalVersionValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); 591 this.Messaging.Write(ErrorMessages.IllegalVersionValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
588 } 592 }
589 593
590 return null; 594 return null;
@@ -608,7 +612,7 @@ namespace WixToolset.Core.ExtensibilityServices
608 return YesNoDefaultType.Default; 612 return YesNoDefaultType.Default;
609 613
610 default: 614 default:
611 Messaging.Instance.OnMessage(WixErrors.IllegalYesNoDefaultValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); 615 this.Messaging.Write(ErrorMessages.IllegalYesNoDefaultValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
612 return YesNoDefaultType.IllegalValue; 616 return YesNoDefaultType.IllegalValue;
613 } 617 }
614 } 618 }
@@ -628,7 +632,7 @@ namespace WixToolset.Core.ExtensibilityServices
628 return YesNoType.No; 632 return YesNoType.No;
629 633
630 default: 634 default:
631 Messaging.Instance.OnMessage(WixErrors.IllegalYesNoValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); 635 this.Messaging.Write(ErrorMessages.IllegalYesNoValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
632 return YesNoType.IllegalValue; 636 return YesNoType.IllegalValue;
633 } 637 }
634 } 638 }
@@ -722,7 +726,7 @@ namespace WixToolset.Core.ExtensibilityServices
722 else 726 else
723 { 727 {
724 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(element); 728 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(element);
725 Messaging.Instance.OnMessage(WixErrors.UnhandledExtensionAttribute(sourceLineNumbers, element.Name.LocalName, attribute.Name.LocalName, attribute.Name.NamespaceName)); 729 this.Messaging.Write(ErrorMessages.UnhandledExtensionAttribute(sourceLineNumbers, element.Name.LocalName, attribute.Name.LocalName, attribute.Name.NamespaceName));
726 } 730 }
727 } 731 }
728 732
@@ -736,7 +740,7 @@ namespace WixToolset.Core.ExtensibilityServices
736 else 740 else
737 { 741 {
738 var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(element); 742 var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(element);
739 Messaging.Instance.OnMessage(WixErrors.UnhandledExtensionElement(childSourceLineNumbers, parentElement.Name.LocalName, element.Name.LocalName, element.Name.NamespaceName)); 743 this.Messaging.Write(ErrorMessages.UnhandledExtensionElement(childSourceLineNumbers, parentElement.Name.LocalName, element.Name.LocalName, element.Name.NamespaceName));
740 } 744 }
741 } 745 }
742 746
@@ -751,7 +755,7 @@ namespace WixToolset.Core.ExtensibilityServices
751 else 755 else
752 { 756 {
753 var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(element); 757 var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(element);
754 Messaging.Instance.OnMessage(WixErrors.UnhandledExtensionElement(childSourceLineNumbers, parentElement.Name.LocalName, element.Name.LocalName, element.Name.NamespaceName)); 758 this.Messaging.Write(ErrorMessages.UnhandledExtensionElement(childSourceLineNumbers, parentElement.Name.LocalName, element.Name.LocalName, element.Name.NamespaceName));
755 } 759 }
756 760
757 return keyPath; 761 return keyPath;
@@ -775,13 +779,13 @@ namespace WixToolset.Core.ExtensibilityServices
775 public void UnexpectedAttribute(XElement element, XAttribute attribute) 779 public void UnexpectedAttribute(XElement element, XAttribute attribute)
776 { 780 {
777 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(element); 781 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(element);
778 Common.UnexpectedAttribute(sourceLineNumbers, attribute); 782 Common.UnexpectedAttribute(this.Messaging, sourceLineNumbers, attribute);
779 } 783 }
780 784
781 public void UnexpectedElement(XElement parentElement, XElement childElement) 785 public void UnexpectedElement(XElement parentElement, XElement childElement)
782 { 786 {
783 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(childElement); 787 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(childElement);
784 Messaging.Instance.OnMessage(WixErrors.UnexpectedElement(sourceLineNumbers, parentElement.Name.LocalName, childElement.Name.LocalName)); 788 this.Messaging.Write(ErrorMessages.UnexpectedElement(sourceLineNumbers, parentElement.Name.LocalName, childElement.Name.LocalName));
785 } 789 }
786 790
787 private void CreateTupleDefinitionCreator() 791 private void CreateTupleDefinitionCreator()
diff --git a/src/WixToolset.Core/ExtensibilityServices/PreprocessHelper.cs b/src/WixToolset.Core/ExtensibilityServices/PreprocessHelper.cs
index bcbd6a67..0e3e0bfd 100644
--- a/src/WixToolset.Core/ExtensibilityServices/PreprocessHelper.cs
+++ b/src/WixToolset.Core/ExtensibilityServices/PreprocessHelper.cs
@@ -42,7 +42,7 @@ namespace WixToolset.Core.ExtensibilityServices
42 { 42 {
43 if (showWarning) 43 if (showWarning)
44 { 44 {
45 context.Messaging.OnMessage(WixWarnings.VariableDeclarationCollision(context.CurrentSourceLineNumber, name, value, currentValue)); 45 context.Messaging.Write(WarningMessages.VariableDeclarationCollision(context.CurrentSourceLineNumber, name, value, currentValue));
46 } 46 }
47 47
48 context.Variables[name] = value; 48 context.Variables[name] = value;
@@ -56,7 +56,7 @@ namespace WixToolset.Core.ExtensibilityServices
56 // Check to make sure there are 2 parts and neither is an empty string. 56 // Check to make sure there are 2 parts and neither is an empty string.
57 if (2 != prefixParts.Length || 0 >= prefixParts[0].Length || 0 >= prefixParts[1].Length) 57 if (2 != prefixParts.Length || 0 >= prefixParts[0].Length || 0 >= prefixParts[1].Length)
58 { 58 {
59 throw new WixException(WixErrors.InvalidPreprocessorFunction(context.CurrentSourceLineNumber, function)); 59 throw new WixException(ErrorMessages.InvalidPreprocessorFunction(context.CurrentSourceLineNumber, function));
60 } 60 }
61 61
62 var prefix = prefixParts[0]; 62 var prefix = prefixParts[0];
@@ -65,7 +65,7 @@ namespace WixToolset.Core.ExtensibilityServices
65 // Check to make sure there are 2 parts, neither is an empty string, and the second part ends with a closing paren. 65 // Check to make sure there are 2 parts, neither is an empty string, and the second part ends with a closing paren.
66 if (2 != functionParts.Length || 0 >= functionParts[0].Length || 0 >= functionParts[1].Length || !functionParts[1].EndsWith(")", StringComparison.Ordinal)) 66 if (2 != functionParts.Length || 0 >= functionParts[0].Length || 0 >= functionParts[1].Length || !functionParts[1].EndsWith(")", StringComparison.Ordinal))
67 { 67 {
68 throw new WixException(WixErrors.InvalidPreprocessorFunction(context.CurrentSourceLineNumber, function)); 68 throw new WixException(ErrorMessages.InvalidPreprocessorFunction(context.CurrentSourceLineNumber, function));
69 } 69 }
70 70
71 var functionName = functionParts[0]; 71 var functionName = functionParts[0];
@@ -113,7 +113,7 @@ namespace WixToolset.Core.ExtensibilityServices
113 // Make sure the base version is specified 113 // Make sure the base version is specified
114 if (args.Length == 0 || String.IsNullOrEmpty(args[0])) 114 if (args.Length == 0 || String.IsNullOrEmpty(args[0]))
115 { 115 {
116 throw new WixException(WixErrors.InvalidPreprocessorFunctionAutoVersion(context.CurrentSourceLineNumber)); 116 throw new WixException(ErrorMessages.InvalidPreprocessorFunctionAutoVersion(context.CurrentSourceLineNumber));
117 } 117 }
118 118
119 // Build = days since 1/1/2000; Revision = seconds since midnight / 2 119 // Build = days since 1/1/2000; Revision = seconds since midnight / 2
@@ -137,7 +137,7 @@ namespace WixToolset.Core.ExtensibilityServices
137 } 137 }
138 catch (Exception e) 138 catch (Exception e)
139 { 139 {
140 throw new WixException(WixErrors.PreprocessorExtensionEvaluateFunctionFailed(context.CurrentSourceLineNumber, prefix, function, String.Join(",", args), e.Message)); 140 throw new WixException(ErrorMessages.PreprocessorExtensionEvaluateFunctionFailed(context.CurrentSourceLineNumber, prefix, function, String.Join(",", args), e.Message));
141 } 141 }
142 } 142 }
143 else 143 else
@@ -165,7 +165,7 @@ namespace WixToolset.Core.ExtensibilityServices
165 } 165 }
166 else 166 else
167 { 167 {
168 throw new WixException(WixErrors.InvalidPreprocessorVariable(context.CurrentSourceLineNumber, variable)); 168 throw new WixException(ErrorMessages.InvalidPreprocessorVariable(context.CurrentSourceLineNumber, variable));
169 } 169 }
170 } 170 }
171 else 171 else
@@ -185,7 +185,7 @@ namespace WixToolset.Core.ExtensibilityServices
185 } 185 }
186 else 186 else
187 { 187 {
188 throw new WixException(WixErrors.InvalidPreprocessorVariable(context.CurrentSourceLineNumber, variable)); 188 throw new WixException(ErrorMessages.InvalidPreprocessorVariable(context.CurrentSourceLineNumber, variable));
189 } 189 }
190 } 190 }
191 } 191 }
@@ -220,7 +220,7 @@ namespace WixToolset.Core.ExtensibilityServices
220 return context.CurrentSourceLineNumber.FileName; 220 return context.CurrentSourceLineNumber.FileName;
221 221
222 case "PLATFORM": 222 case "PLATFORM":
223 context.Messaging.OnMessage(WixWarnings.DeprecatedPreProcVariable(context.CurrentSourceLineNumber, "$(sys.PLATFORM)", "$(sys.BUILDARCH)")); 223 context.Messaging.Write(WarningMessages.DeprecatedPreProcVariable(context.CurrentSourceLineNumber, "$(sys.PLATFORM)", "$(sys.BUILDARCH)"));
224 224
225 goto case "BUILDARCH"; 225 goto case "BUILDARCH";
226 226
@@ -260,7 +260,7 @@ namespace WixToolset.Core.ExtensibilityServices
260 } 260 }
261 catch (Exception e) 261 catch (Exception e)
262 { 262 {
263 throw new WixException(WixErrors.PreprocessorExtensionGetVariableValueFailed(context.CurrentSourceLineNumber, prefix, name, e.Message)); 263 throw new WixException(ErrorMessages.PreprocessorExtensionGetVariableValueFailed(context.CurrentSourceLineNumber, prefix, name, e.Message));
264 } 264 }
265 } 265 }
266 else 266 else
@@ -277,7 +277,7 @@ namespace WixToolset.Core.ExtensibilityServices
277 // Check to make sure there are 2 parts and neither is an empty string. 277 // Check to make sure there are 2 parts and neither is an empty string.
278 if (2 != prefixParts.Length) 278 if (2 != prefixParts.Length)
279 { 279 {
280 throw new WixException(WixErrors.InvalidPreprocessorPragma(context.CurrentSourceLineNumber, pragmaName)); 280 throw new WixException(ErrorMessages.InvalidPreprocessorPragma(context.CurrentSourceLineNumber, pragmaName));
281 } 281 }
282 282
283 var prefix = prefixParts[0]; 283 var prefix = prefixParts[0];
@@ -285,7 +285,7 @@ namespace WixToolset.Core.ExtensibilityServices
285 285
286 if (String.IsNullOrEmpty(prefix) || String.IsNullOrEmpty(pragma)) 286 if (String.IsNullOrEmpty(prefix) || String.IsNullOrEmpty(pragma))
287 { 287 {
288 throw new WixException(WixErrors.InvalidPreprocessorPragma(context.CurrentSourceLineNumber, pragmaName)); 288 throw new WixException(ErrorMessages.InvalidPreprocessorPragma(context.CurrentSourceLineNumber, pragmaName));
289 } 289 }
290 290
291 switch (prefix) 291 switch (prefix)
@@ -295,7 +295,7 @@ namespace WixToolset.Core.ExtensibilityServices
295 { 295 {
296 // Add any core defined pragmas here 296 // Add any core defined pragmas here
297 default: 297 default:
298 context.Messaging.OnMessage(WixWarnings.PreprocessorUnknownPragma(context.CurrentSourceLineNumber, pragmaName)); 298 context.Messaging.Write(WarningMessages.PreprocessorUnknownPragma(context.CurrentSourceLineNumber, pragmaName));
299 break; 299 break;
300 } 300 }
301 break; 301 break;
@@ -306,7 +306,7 @@ namespace WixToolset.Core.ExtensibilityServices
306 { 306 {
307 if (!extension.ProcessPragma(prefix, pragma, args, parent)) 307 if (!extension.ProcessPragma(prefix, pragma, args, parent))
308 { 308 {
309 context.Messaging.OnMessage(WixWarnings.PreprocessorUnknownPragma(context.CurrentSourceLineNumber, pragmaName)); 309 context.Messaging.Write(WarningMessages.PreprocessorUnknownPragma(context.CurrentSourceLineNumber, pragmaName));
310 } 310 }
311 } 311 }
312 break; 312 break;
@@ -339,7 +339,7 @@ namespace WixToolset.Core.ExtensibilityServices
339 currentPosition = remainder.IndexOf(')'); 339 currentPosition = remainder.IndexOf(')');
340 if (-1 == currentPosition) 340 if (-1 == currentPosition)
341 { 341 {
342 context.Messaging.OnMessage(WixErrors.InvalidPreprocessorVariable(context.CurrentSourceLineNumber, remainder)); 342 context.Messaging.Write(ErrorMessages.InvalidPreprocessorVariable(context.CurrentSourceLineNumber, remainder));
343 break; 343 break;
344 } 344 }
345 345
@@ -385,12 +385,12 @@ namespace WixToolset.Core.ExtensibilityServices
385 { 385 {
386 if (isFunction) 386 if (isFunction)
387 { 387 {
388 context.Messaging.OnMessage(WixErrors.InvalidPreprocessorFunction(context.CurrentSourceLineNumber, remainder)); 388 context.Messaging.Write(ErrorMessages.InvalidPreprocessorFunction(context.CurrentSourceLineNumber, remainder));
389 break; 389 break;
390 } 390 }
391 else 391 else
392 { 392 {
393 context.Messaging.OnMessage(WixErrors.InvalidPreprocessorVariable(context.CurrentSourceLineNumber, remainder)); 393 context.Messaging.Write(ErrorMessages.InvalidPreprocessorVariable(context.CurrentSourceLineNumber, remainder));
394 break; 394 break;
395 } 395 }
396 } 396 }
@@ -410,12 +410,12 @@ namespace WixToolset.Core.ExtensibilityServices
410 { 410 {
411 if (isFunction) 411 if (isFunction)
412 { 412 {
413 context.Messaging.OnMessage(WixErrors.UndefinedPreprocessorFunction(context.CurrentSourceLineNumber, subString)); 413 context.Messaging.Write(ErrorMessages.UndefinedPreprocessorFunction(context.CurrentSourceLineNumber, subString));
414 break; 414 break;
415 } 415 }
416 else 416 else
417 { 417 {
418 context.Messaging.OnMessage(WixErrors.UndefinedPreprocessorVariable(context.CurrentSourceLineNumber, subString)); 418 context.Messaging.Write(ErrorMessages.UndefinedPreprocessorVariable(context.CurrentSourceLineNumber, subString));
419 break; 419 break;
420 } 420 }
421 } 421 }
@@ -448,7 +448,7 @@ namespace WixToolset.Core.ExtensibilityServices
448 { 448 {
449 if (!context.Variables.Remove(name)) 449 if (!context.Variables.Remove(name))
450 { 450 {
451 context.Messaging.OnMessage(WixErrors.CannotReundefineVariable(context.CurrentSourceLineNumber, name)); 451 context.Messaging.Write(ErrorMessages.CannotReundefineVariable(context.CurrentSourceLineNumber, name));
452 } 452 }
453 } 453 }
454 454