Changed the coverter to use Messages rather than Errors
Mark Stega committed
Jan 20, 2022 at 15:47 UTC
08b1dd325761edf6bdc2bca38d614611f3eaaa66
1 file changed
+127
-86
src/wix/WixToolset.Converters/WixConverter.cs
+127
-86
@@ -279,7 +279,7 @@ namespace WixToolset.Converters
279
280
private CustomTableTarget CustomTableSetting { get; }
281
282
- private int Errors { get; set; }
282
+ private int Messages { get; set; }
283
284
private HashSet<ConverterTestType> ErrorsAsWarnings { get; set; }
285
@@ -301,8 +301,8 @@ namespace WixToolset.Converters
301
/// Convert a file.
302
/// </summary>
303
/// <param name="sourceFile">The file to convert.</param>
304
- /// <param name="saveConvertedFile">Option to save the converted errors that are found.</param>
305
- /// <returns>The number of errors found.</returns>
304
+ /// <param name="saveConvertedFile">Option to save the converted Messages that are found.</param>
305
+ /// <returns>The number of Messages found.</returns>
306
public int ConvertFile(string sourceFile, bool saveConvertedFile)
307
{
308
var document = this.OpenSourceFile(sourceFile);
@@ -314,30 +314,30 @@ namespace WixToolset.Converters
314
315
this.ConvertDocument(document);
316
317
- // Fix errors if requested and necessary.
318
- if (saveConvertedFile && 0 < this.Errors)
317
+ // Fix Messages if requested and necessary.
318
+ if (saveConvertedFile && 0 < this.Messages)
319
{
320
this.SaveDocument(document);
321
}
322
323
- return this.Errors;
323
+ return this.Messages;
324
}
325
326
/// <summary>
327
/// Convert a document.
328
/// </summary>
329
/// <param name="document">The document to convert.</param>
330
- /// <returns>The number of errors found.</returns>
330
+ /// <returns>The number of Messages found.</returns>
331
public int ConvertDocument(XDocument document)
332
{
333
// Reset the instance info.
334
- this.Errors = 0;
334
+ this.Messages = 0;
335
this.SourceVersion = 0;
336
this.Operation = ConvertOperation.Convert;
337
338
// Remove the declaration.
339
if (null != document.Declaration
340
- && this.OnError(ConverterTestType.DeclarationPresent, null, "This file contains an XML declaration on the first line."))
340
+ && this.OnInformation(ConverterTestType.DeclarationPresent, null, "This file contains an XML declaration on the first line."))
341
{
342
document.Declaration = null;
343
TrimLeadingText(document);
@@ -349,15 +349,15 @@ namespace WixToolset.Converters
349
this.ConvertNodes(document.Nodes(), 0);
350
this.RemoveUnusedNamespaces(document.Root);
351
352
- return this.Errors;
352
+ return this.Messages;
353
}
354
355
/// <summary>
356
/// Format a file.
357
/// </summary>
358
/// <param name="sourceFile">The file to format.</param>
359
- /// <param name="saveConvertedFile">Option to save the format errors that are found.</param>
360
- /// <returns>The number of errors found.</returns>
359
+ /// <param name="saveConvertedFile">Option to save the format Messages that are found.</param>
360
+ /// <returns>The number of Messages found.</returns>
361
public int FormatFile(string sourceFile, bool saveConvertedFile)
362
{
363
var document = this.OpenSourceFile(sourceFile);
@@ -369,30 +369,30 @@ namespace WixToolset.Converters
369
370
this.FormatDocument(document);
371
372
- // Fix errors if requested and necessary.
373
- if (saveConvertedFile && 0 < this.Errors)
372
+ // Fix Messages if requested and necessary.
373
+ if (saveConvertedFile && 0 < this.Messages)
374
{
375
this.SaveDocument(document);
376
}
377
378
- return this.Errors;
378
+ return this.Messages;
379
}
380
381
/// <summary>
382
/// Format a document.
383
/// </summary>
384
/// <param name="document">The document to format.</param>
385
- /// <returns>The number of errors found.</returns>
385
+ /// <returns>The number of Messages found.</returns>
386
public int FormatDocument(XDocument document)
387
{
388
// Reset the instance info.
389
- this.Errors = 0;
389
+ this.Messages = 0;
390
this.SourceVersion = 0;
391
this.Operation = ConvertOperation.Format;
392
393
// Remove the declaration.
394
if (null != document.Declaration
395
- && this.OnError(ConverterTestType.DeclarationPresent, null, "This file contains an XML declaration on the first line."))
395
+ && this.OnInformation(ConverterTestType.DeclarationPresent, null, "This file contains an XML declaration on the first line."))
396
{
397
document.Declaration = null;
398
TrimLeadingText(document);
@@ -402,7 +402,7 @@ namespace WixToolset.Converters
402
this.ConvertNodes(document.Nodes(), 0);
403
this.RemoveUnusedNamespaces(document.Root);
404
405
- return this.Errors;
405
+ return this.Messages;
406
}
407
408
private XDocument OpenSourceFile(string sourceFile)
@@ -521,7 +521,7 @@ namespace WixToolset.Converters
521
{
522
var message = testType == ConverterTestType.WhitespacePrecedingEndElementWrong ? "The whitespace preceding this end element is incorrect." : "The whitespace preceding this node is incorrect.";
523
524
- if (this.OnError(testType, node, message))
524
+ if (this.OnInformation(testType, node, message))
525
{
526
WixConverter.FixupWhitespace(this.IndentationAmount, level, whitespace);
527
}
@@ -534,7 +534,7 @@ namespace WixToolset.Converters
534
{
535
var message = testType == ConverterTestType.WhitespacePrecedingEndElementWrong ? "The whitespace preceding this end element is incorrect." : "The whitespace preceding this node is incorrect.";
536
537
- if (this.OnError(testType, node, message))
537
+ if (this.OnInformation(testType, node, message))
538
{
539
whitespace.Remove();
540
}
@@ -563,7 +563,7 @@ namespace WixToolset.Converters
563
564
if (WixConverter.OldToNewNamespaceMapping.TryGetValue(declaration.Value, out var ns))
565
{
566
- if (this.OnError(ConverterTestType.XmlnsValueWrong, declaration, "The namespace '{0}' is out of date. It must be '{1}'.", declaration.Value, ns.NamespaceName))
566
+ if (this.OnInformation(ConverterTestType.XmlnsValueWrong, declaration, "The namespace '{0}' is out of date. It must be '{1}'.", declaration.Value, ns.NamespaceName))
567
{
568
deprecatedToUpdatedNamespaces.Add(declaration.Value, ns);
569
}
@@ -597,7 +597,7 @@ namespace WixToolset.Converters
597
{
598
var xUseUILanguages = element.Attribute(BalUseUILanguagesName);
599
if (xUseUILanguages != null &&
600
- this.OnError(ConverterTestType.BalUseUILanguagesDeprecated, element, "bal:UseUILanguages is deprecated, 'true' is now the standard behavior."))
600
+ this.OnInformation(ConverterTestType.BalUseUILanguagesDeprecated, element, "bal:UseUILanguages is deprecated, 'true' is now the standard behavior."))
601
{
602
xUseUILanguages.Remove();
603
}
@@ -669,7 +669,7 @@ namespace WixToolset.Converters
669
670
bool CreateBADllElement(XObject node, out XElement xCreatedBADll)
671
{
672
- var create = this.OnError(ConverterTestType.BootstrapperApplicationDll, node, "The bootstrapper application dll is now specified in the BootstrapperApplicationDll element.");
672
+ var create = this.OnInformation(ConverterTestType.BootstrapperApplicationDll, node, "The bootstrapper application dll is now specified in the BootstrapperApplicationDll element.");
673
xCreatedBADll = create ? new XElement(BootstrapperApplicationDllElementName) : null;
674
return create;
675
}
@@ -679,7 +679,7 @@ namespace WixToolset.Converters
679
{
680
var xUseUILanguages = element.Attribute(BalUseUILanguagesName);
681
if (xUseUILanguages != null &&
682
- this.OnError(ConverterTestType.BalUseUILanguagesDeprecated, element, "bal:UseUILanguages is deprecated, 'true' is now the standard behavior."))
682
+ this.OnInformation(ConverterTestType.BalUseUILanguagesDeprecated, element, "bal:UseUILanguages is deprecated, 'true' is now the standard behavior."))
683
{
684
xUseUILanguages.Remove();
685
}
@@ -781,7 +781,7 @@ namespace WixToolset.Converters
781
782
private void ConvertCatalogElement(XElement element)
783
{
784
- if (this.OnError(ConverterTestType.BundleSignatureValidationObsolete, element, "The Catalog element is obsolete. Signature validation is no longer supported. The element will be removed."))
784
+ if (this.OnInformation(ConverterTestType.BundleSignatureValidationObsolete, element, "The Catalog element is obsolete. Signature validation is no longer supported. The element will be removed."))
785
{
786
element.Remove();
787
}
@@ -817,7 +817,7 @@ namespace WixToolset.Converters
817
var bootstrapperApplicationData = element.Attribute("BootstrapperApplicationData");
818
if (bootstrapperApplicationData?.Value == "no")
819
{
820
- if (this.OnError(ConverterTestType.BootstrapperApplicationDataDeprecated, element, "The CustomTable element contains deprecated '{0}' attribute. Use the 'Unreal' attribute instead.", bootstrapperApplicationData.Name))
820
+ if (this.OnInformation(ConverterTestType.BootstrapperApplicationDataDeprecated, element, "The CustomTable element contains deprecated '{0}' attribute. Use the 'Unreal' attribute instead.", bootstrapperApplicationData.Name))
821
{
822
bootstrapperApplicationData.Remove();
823
}
@@ -858,14 +858,14 @@ namespace WixToolset.Converters
858
switch (this.CustomTableSetting)
859
{
860
case CustomTableTarget.Bundle:
861
- if (this.OnError(ConverterTestType.CustomTableRef, element, "CustomTable elements that don't contain the table definition are now BundleCustomDataRef for Bundles."))
861
+ if (this.OnInformation(ConverterTestType.CustomTableRef, element, "CustomTable elements that don't contain the table definition are now BundleCustomDataRef for Bundles."))
862
{
863
element.Name = WixConverter.BundleCustomDataRefElementName;
864
this.ConvertCustomTableElementToBundle(element);
865
}
866
break;
867
case CustomTableTarget.Msi:
868
- if (this.OnError(ConverterTestType.CustomTableRef, element, "CustomTable elements that don't contain the table definition are now CustomTableRef for MSI."))
868
+ if (this.OnInformation(ConverterTestType.CustomTableRef, element, "CustomTable elements that don't contain the table definition are now CustomTableRef for MSI."))
869
{
870
element.Name = WixConverter.CustomTableRefElementName;
871
}
@@ -925,7 +925,7 @@ namespace WixToolset.Converters
925
var action = UppercaseFirstChar(xCondition.Attribute("Action")?.Value);
926
if (!String.IsNullOrEmpty(action) &&
927
TryGetInnerText(xCondition, out var text) &&
928
- this.OnError(ConverterTestType.InnerTextDeprecated, element, "Using {0} element text is deprecated. Use the '{1}Condition' attribute instead.", xCondition.Name.LocalName, action))
928
+ this.OnInformation(ConverterTestType.InnerTextDeprecated, element, "Using {0} element text is deprecated. Use the '{1}Condition' attribute instead.", xCondition.Name.LocalName, action))
929
{
930
element.Add(new XAttribute(action + "Condition", text));
931
remove.Add(xCondition);
@@ -943,7 +943,7 @@ namespace WixToolset.Converters
943
var guid = element.Attribute("Guid");
944
if (guid != null && guid.Value == "*")
945
{
946
- if (this.OnError(ConverterTestType.AutoGuidUnnecessary, element, "Using '*' for the Component Guid attribute is unnecessary. Remove the attribute to remove the redundancy."))
946
+ if (this.OnInformation(ConverterTestType.AutoGuidUnnecessary, element, "Using '*' for the Component Guid attribute is unnecessary. Remove the attribute to remove the redundancy."))
947
{
948
guid.Remove();
949
}
@@ -953,7 +953,7 @@ namespace WixToolset.Converters
953
if (xCondition != null)
954
{
955
if (TryGetInnerText(xCondition, out var text) &&
956
- this.OnError(ConverterTestType.InnerTextDeprecated, element, "Using {0} element text is deprecated. Use the 'Condition' attribute instead.", xCondition.Name.LocalName))
956
+ this.OnInformation(ConverterTestType.InnerTextDeprecated, element, "Using {0} element text is deprecated. Use the 'Condition' attribute instead.", xCondition.Name.LocalName))
957
{
958
element.Add(new XAttribute("Condition", text));
959
xCondition.Remove();
@@ -971,7 +971,7 @@ namespace WixToolset.Converters
971
if (null != attribute)
972
{
973
var shortName = attribute.Value;
974
- if (this.OnError(ConverterTestType.AssignDirectoryNameFromShortName, element, "The directory ShortName attribute is being renamed to Name since Name wasn't specified for value '{0}'", shortName))
974
+ if (this.OnInformation(ConverterTestType.AssignDirectoryNameFromShortName, element, "The directory ShortName attribute is being renamed to Name since Name wasn't specified for value '{0}'", shortName))
975
{
976
element.Add(new XAttribute("Name", shortName));
977
attribute.Remove();
@@ -982,7 +982,7 @@ namespace WixToolset.Converters
982
var id = element.Attribute("Id")?.Value;
983
984
if (id == "TARGETDIR" &&
985
- this.OnError(ConverterTestType.TargetDirDeprecated, element, "The TARGETDIR directory should not longer be explicitly defined. Remove the Directory element with Id attribute 'TARGETDIR'."))
985
+ this.OnInformation(ConverterTestType.TargetDirDeprecated, element, "The TARGETDIR directory should not longer be explicitly defined. Remove the Directory element with Id attribute 'TARGETDIR'."))
986
{
987
var parentElement = element.Parent;
988
@@ -1007,7 +1007,7 @@ namespace WixToolset.Converters
1007
}
1008
else if (id != null &&
1009
WindowsInstallerStandard.IsStandardDirectory(id) &&
1010
- this.OnError(ConverterTestType.DefiningStandardDirectoryDeprecated, element, "Standard directories such as '{0}' should no longer be defined using the Directory element. Use the StandardDirectory element instead.", id))
1010
+ this.OnInformation(ConverterTestType.DefiningStandardDirectoryDeprecated, element, "Standard directories such as '{0}' should no longer be defined using the Directory element. Use the StandardDirectory element instead.", id))
1011
{
1012
element.Name = StandardDirectoryElementName;
1013
@@ -1022,7 +1022,7 @@ namespace WixToolset.Converters
1022
{
1023
var xAbsent = element.Attribute("Absent");
1024
if (xAbsent != null &&
1025
- this.OnError(ConverterTestType.FeatureAbsentAttributeReplaced, element, "The Feature element's Absent attribute has been replaced with the AllowAbsent attribute. Use the 'AllowAbsent' attribute instead."))
1025
+ this.OnInformation(ConverterTestType.FeatureAbsentAttributeReplaced, element, "The Feature element's Absent attribute has been replaced with the AllowAbsent attribute. Use the 'AllowAbsent' attribute instead."))
1026
{
1027
if (xAbsent.Value == "disallow")
1028
{
@@ -1035,12 +1035,12 @@ namespace WixToolset.Converters
1035
if (xAllowAdvertise != null)
1036
{
1037
if ((xAllowAdvertise.Value == "system" || xAllowAdvertise.Value == "allow") &&
1038
- this.OnError(ConverterTestType.FeatureAllowAdvertiseValueDeprecated, element, "The AllowAdvertise attribute's '{0}' value is deprecated. Set the value to 'yes' instead.", xAllowAdvertise.Value))
1038
+ this.OnInformation(ConverterTestType.FeatureAllowAdvertiseValueDeprecated, element, "The AllowAdvertise attribute's '{0}' value is deprecated. Set the value to 'yes' instead.", xAllowAdvertise.Value))
1039
{
1040
xAllowAdvertise.Value = "yes";
1041
}
1042
else if (xAllowAdvertise.Value == "disallow" &&
1043
- this.OnError(ConverterTestType.FeatureAllowAdvertiseValueDeprecated, element, "The AllowAdvertise attribute's '{0}' value is deprecated. Remove the value instead.", xAllowAdvertise.Value))
1043
+ this.OnInformation(ConverterTestType.FeatureAllowAdvertiseValueDeprecated, element, "The AllowAdvertise attribute's '{0}' value is deprecated. Remove the value instead.", xAllowAdvertise.Value))
1044
{
1045
xAllowAdvertise.Remove();
1046
}
@@ -1052,7 +1052,7 @@ namespace WixToolset.Converters
1052
var level = xCondition.Attribute("Level")?.Value;
1053
if (!String.IsNullOrEmpty(level) &&
1054
TryGetInnerText(xCondition, out var text) &&
1055
- this.OnError(ConverterTestType.InnerTextDeprecated, element, "Using {0} element text is deprecated. Use the 'Level' element instead.", xCondition.Name.LocalName))
1055
+ this.OnInformation(ConverterTestType.InnerTextDeprecated, element, "Using {0} element text is deprecated. Use the 'Level' element instead.", xCondition.Name.LocalName))
1056
{
1057
xCondition.AddAfterSelf(new XElement(LevelElementName,
1058
new XAttribute("Value", level),
@@ -1078,7 +1078,7 @@ namespace WixToolset.Converters
1078
{
1079
var name = Path.GetFileName(attribute.Value);
1080
1081
- if (this.OnError(ConverterTestType.AssignAnonymousFileId, element, "The file id is being updated to '{0}' to ensure it remains the same as the v3 default", name))
1081
+ if (this.OnInformation(ConverterTestType.AssignAnonymousFileId, element, "The file id is being updated to '{0}' to ensure it remains the same as the v3 default", name))
1082
{
1083
IEnumerable<XAttribute> attributes = element.Attributes().ToList();
1084
element.RemoveAttributes();
@@ -1099,7 +1099,7 @@ namespace WixToolset.Converters
1099
1100
if (!String.IsNullOrEmpty(message) &&
1101
TryGetInnerText(xCondition, out var text) &&
1102
- this.OnError(ConverterTestType.InnerTextDeprecated, element, "Using {0} element text is deprecated. Use the 'Launch' element instead.", xCondition.Name.LocalName))
1102
+ this.OnInformation(ConverterTestType.InnerTextDeprecated, element, "Using {0} element text is deprecated. Use the 'Launch' element instead.", xCondition.Name.LocalName))
1103
{
1104
xCondition.AddAfterSelf(new XElement(LaunchElementName,
1105
new XAttribute("Condition", text),
@@ -1133,7 +1133,7 @@ namespace WixToolset.Converters
1133
var attribute = element.Attribute(attributeName);
1134
1135
if (attribute != null &&
1136
- this.OnError(ConverterTestType.RenameExePackageCommandToArguments, element, "The {0} element {1} attribute has been renamed {2}.", element.Name.LocalName, attribute.Name.LocalName, newName))
1136
+ this.OnInformation(ConverterTestType.RenameExePackageCommandToArguments, element, "The {0} element {1} attribute has been renamed {2}.", element.Name.LocalName, attribute.Name.LocalName, newName))
1137
{
1138
element.Add(new XAttribute(newName, attribute.Value));
1139
attribute.Remove();
@@ -1147,7 +1147,7 @@ namespace WixToolset.Converters
1147
if (xCondition != null)
1148
{
1149
if (TryGetInnerText(xCondition, out var text) &&
1150
- this.OnError(ConverterTestType.InnerTextDeprecated, element, "Using {0} element text is deprecated. Use the 'Condition' attribute instead.", xCondition.Name.LocalName))
1150
+ this.OnInformation(ConverterTestType.InnerTextDeprecated, element, "Using {0} element text is deprecated. Use the 'Condition' attribute instead.", xCondition.Name.LocalName))
1151
{
1152
element.Add(new XAttribute("Condition", text));
1153
xCondition.Remove();
@@ -1160,7 +1160,7 @@ namespace WixToolset.Converters
1160
private void ConvertModuleElement(XElement element)
1161
{
1162
if (element.Attribute("Guid") == null // skip already-converted Module elements
1163
- && this.OnError(ConverterTestType.ModuleAndPackageRenamed, element, "The Module and Package elements have been renamed and reorganized for simplicity."))
1163
+ && this.OnInformation(ConverterTestType.ModuleAndPackageRenamed, element, "The Module and Package elements have been renamed and reorganized for simplicity."))
1164
{
1165
var xModule = element;
1166
@@ -1172,7 +1172,7 @@ namespace WixToolset.Converters
1172
var xInstallerVersion = xSummaryInformation.Attribute("InstallerVersion");
1173
if (this.SourceVersion < 4 && xInstallerVersion == null)
1174
{
1175
- this.OnError(ConverterTestType.InstallerVersionBehaviorChange, element, "Breaking change: The default value for Package/@InstallerVersion has been changed to '500' regardless of build platform. If you need a lower version, set it manually in the Module element.");
1175
+ this.OnInformation(ConverterTestType.InstallerVersionBehaviorChange, element, "Breaking change: The default value for Package/@InstallerVersion has been changed to '500' regardless of build platform. If you need a lower version, set it manually in the Module element.");
1176
}
1177
1178
RemoveAttribute(xSummaryInformation, "AdminImage");
@@ -1205,7 +1205,7 @@ namespace WixToolset.Converters
1205
var id = element.Attribute("Id");
1206
if (id != null && id.Value == "*")
1207
{
1208
- if (this.OnError(ConverterTestType.AutoGuidUnnecessary, element, "Using '*' for the Product Id attribute is unnecessary. Remove the attribute to remove the redundancy."))
1208
+ if (this.OnInformation(ConverterTestType.AutoGuidUnnecessary, element, "Using '*' for the Product Id attribute is unnecessary. Remove the attribute to remove the redundancy."))
1209
{
1210
id.Remove();
1211
}
@@ -1218,7 +1218,7 @@ namespace WixToolset.Converters
1218
1219
if (!String.IsNullOrEmpty(message) &&
1220
TryGetInnerText(xCondition, out var text) &&
1221
- this.OnError(ConverterTestType.InnerTextDeprecated, element, "Using {0} element text is deprecated. Use the 'Launch' element instead.", xCondition.Name.LocalName))
1221
+ this.OnInformation(ConverterTestType.InnerTextDeprecated, element, "Using {0} element text is deprecated. Use the 'Launch' element instead.", xCondition.Name.LocalName))
1222
{
1223
xCondition.AddAfterSelf(new XElement(LaunchElementName,
1224
new XAttribute("Condition", text),
@@ -1235,7 +1235,7 @@ namespace WixToolset.Converters
1235
xMediaTemplate.Remove();
1236
}
1237
1238
- if (this.OnError(ConverterTestType.ProductAndPackageRenamed, element, "The Product and Package elements have been renamed and reorganized for simplicity."))
1238
+ if (this.OnInformation(ConverterTestType.ProductAndPackageRenamed, element, "The Product and Package elements have been renamed and reorganized for simplicity."))
1239
{
1240
var xPackage = element;
1241
xPackage.Name = PackageElementName;
@@ -1248,7 +1248,7 @@ namespace WixToolset.Converters
1248
var xInstallerVersion = xSummaryInformation.Attribute("InstallerVersion");
1249
if (this.SourceVersion < 4 && xInstallerVersion == null)
1250
{
1251
- this.OnError(ConverterTestType.InstallerVersionBehaviorChange, element, "Breaking change: The default value for Package/@InstallerVersion has been changed to '500' regardless of build platform. If you need a lower version, set it manually in the Package element.");
1251
+ this.OnInformation(ConverterTestType.InstallerVersionBehaviorChange, element, "Breaking change: The default value for Package/@InstallerVersion has been changed to '500' regardless of build platform. If you need a lower version, set it manually in the Package element.");
1252
}
1253
1254
if (xSummaryInformation.Attribute("Compressed") == null)
@@ -1497,7 +1497,7 @@ namespace WixToolset.Converters
1497
}
1498
1499
if (!String.IsNullOrEmpty(newElementName)
1500
- && this.OnError(ConverterTestType.ReferencesReplaced, element, "UI, custom action, and property reference {0} has been replaced with strongly-typed element.", id))
1500
+ && this.OnInformation(ConverterTestType.ReferencesReplaced, element, "UI, custom action and property reference {0} have been replaced with strongly-typed elements.", id))
1501
{
1502
element.AddAfterSelf(new XElement(WixUtilNamespace + newElementName));
1503
element.Remove();
@@ -1510,7 +1510,7 @@ namespace WixToolset.Converters
1510
1511
var xCondition = element.Attribute("Condition");
1512
if (xCondition?.Value == "1" &&
1513
- this.OnError(ConverterTestType.PublishConditionOneUnnecessary, element, "Adding Condition='1' on {0} elements is no longer necessary. Remove the Condition attribute.", xCondition.Name.LocalName))
1513
+ this.OnInformation(ConverterTestType.PublishConditionOneUnnecessary, element, "Adding Condition='1' on {0} elements is no longer necessary. Remove the Condition attribute.", xCondition.Name.LocalName))
1514
{
1515
xCondition.Remove();
1516
}
@@ -1523,7 +1523,7 @@ namespace WixToolset.Converters
1523
var xAction = element.Attribute("Action");
1524
1525
if (xAction != null
1526
- && this.OnError(ConverterTestType.RegistryKeyActionObsolete, element, "The RegistryKey element's Action attribute is obsolete. Action='create' will be converted to ForceCreateOnInstall='yes'. Action='createAndRemoveOnUninstall' will be converted to ForceCreateOnInstall='yes' and ForceDeleteOnUninstall='yes'."))
1526
+ && this.OnInformation(ConverterTestType.RegistryKeyActionObsolete, element, "The RegistryKey element's Action attribute is obsolete. Action='create' will be converted to ForceCreateOnInstall='yes'. Action='createAndRemoveOnUninstall' will be converted to ForceCreateOnInstall='yes' and ForceDeleteOnUninstall='yes'."))
1527
{
1528
switch (xAction?.Value)
1529
{
@@ -1545,7 +1545,7 @@ namespace WixToolset.Converters
1545
var xParent = element.Parent;
1546
1547
if (xParent.Name == ExePackageElementName &&
1548
- this.OnError(ConverterTestType.RemotePayloadRenamed, element, "The RemotePayload element has been renamed. Use the 'ExePackagePayload' instead."))
1548
+ this.OnInformation(ConverterTestType.RemotePayloadRenamed, element, "The RemotePayload element has been renamed. Use the 'ExePackagePayload' instead."))
1549
{
1550
element.Name = ExePackagePayloadElementName;
1551
}
@@ -1557,7 +1557,7 @@ namespace WixToolset.Converters
1557
1558
var xName = xParent.Attribute("Name");
1559
if (xName != null &&
1560
- this.OnError(ConverterTestType.NameAttributeMovedToRemotePayload, xParent, "The Name attribute must be specified on the child XxxPackagePayload element when using a remote payload."))
1560
+ this.OnInformation(ConverterTestType.NameAttributeMovedToRemotePayload, xParent, "The Name attribute must be specified on the child XxxPackagePayload element when using a remote payload."))
1561
{
1562
element.SetAttributeValue("Name", xName.Value);
1563
xName.Remove();
@@ -1565,7 +1565,7 @@ namespace WixToolset.Converters
1565
1566
var xDownloadUrl = xParent.Attribute("DownloadUrl");
1567
if (xDownloadUrl != null &&
1568
- this.OnError(ConverterTestType.DownloadUrlAttributeMovedToRemotePayload, xParent, "The DownloadUrl attribute must be specified on the child XxxPackagePayload element when using a remote payload."))
1568
+ this.OnInformation(ConverterTestType.DownloadUrlAttributeMovedToRemotePayload, xParent, "The DownloadUrl attribute must be specified on the child XxxPackagePayload element when using a remote payload."))
1569
{
1570
element.SetAttributeValue("DownloadUrl", xDownloadUrl.Value);
1571
xDownloadUrl.Remove();
@@ -1573,12 +1573,12 @@ namespace WixToolset.Converters
1573
1574
var xCompressed = xParent.Attribute("Compressed");
1575
if (xCompressed != null &&
1576
- this.OnError(ConverterTestType.CompressedAttributeUnnecessaryForRemotePayload, xParent, "The Compressed attribute should not be specified when using a remote payload."))
1576
+ this.OnInformation(ConverterTestType.CompressedAttributeUnnecessaryForRemotePayload, xParent, "The Compressed attribute should not be specified when using a remote payload."))
1577
{
1578
xCompressed.Remove();
1579
}
1580
1581
- this.OnError(ConverterTestType.BurnHashAlgorithmChanged, element, "The hash algorithm for bundles changed from SHA1 to SHA512.");
1581
+ this.OnInformation(ConverterTestType.BurnHashAlgorithmChanged, element, "The hash algorithm for bundles changed from SHA1 to SHA512.");
1582
1583
this.RemoveAttributeIfPresent(element, "CertificatePublicKey", ConverterTestType.BundleSignatureValidationObsolete, "The {0} element contains obsolete '{1}' attribute. Signature validation is no longer supported. The attribute will be removed.");
1584
this.RemoveAttributeIfPresent(element, "CertificateThumbprint", ConverterTestType.BundleSignatureValidationObsolete, "The {0} element contains obsolete '{1}' attribute. Signature validation is no longer supported. The attribute will be removed.");
@@ -1617,7 +1617,7 @@ namespace WixToolset.Converters
1617
}
1618
1619
if (element.Parent.Name == ComponentElementName &&
1620
- this.OnError(ConverterTestType.IntegratedDependencyNamespace, element, "The Provides element has been integrated into the WiX v4 namespace. Add the 'Check' attribute from the WixDependency.wixext to match v3 runtime behavior."))
1620
+ this.OnInformation(ConverterTestType.IntegratedDependencyNamespace, element, "The Provides element has been integrated into the WiX v4 namespace. Add the 'Check' attribute from the WixDependency.wixext to match v3 runtime behavior."))
1621
{
1622
element.Add(new XAttribute(DependencyCheckAttributeName, "yes"));
1623
}
@@ -1625,14 +1625,14 @@ namespace WixToolset.Converters
1625
1626
private void ConvertRequiresElement(XElement element)
1627
{
1628
- if (this.OnError(ConverterTestType.IntegratedDependencyNamespace, element, "The Requires element has been integrated into the WiX v4 namespace. Remove the namespace."))
1628
+ if (this.OnInformation(ConverterTestType.IntegratedDependencyNamespace, element, "The Requires element has been integrated into the WiX v4 namespace. Remove the namespace."))
1629
{
1630
element.Name = RequiresElementName;
1631
}
1632
1633
if (element.Parent.Name == ProvidesElementName &&
1634
element.Parent.Parent?.Name == ComponentElementName &&
1635
- this.OnError(ConverterTestType.IntegratedDependencyNamespace, element, "The Requires element has been integrated into the WiX v4 namespace. Add the 'Enforce' attribute from the WixDependency.wixext to match v3 runtime behavior."))
1635
+ this.OnInformation(ConverterTestType.IntegratedDependencyNamespace, element, "The Requires element has been integrated into the WiX v4 namespace. Add the 'Enforce' attribute from the WixDependency.wixext to match v3 runtime behavior."))
1636
{
1637
element.Add(new XAttribute(DependencyEnforceAttributeName, "yes"));
1638
}
@@ -1640,14 +1640,14 @@ namespace WixToolset.Converters
1640
1641
private void ConvertRequiresRefElement(XElement element)
1642
{
1643
- if (this.OnError(ConverterTestType.IntegratedDependencyNamespace, element, "The RequiresRef element has been integrated into the WiX v4 namespace. Remove the namespace."))
1643
+ if (this.OnInformation(ConverterTestType.IntegratedDependencyNamespace, element, "The RequiresRef element has been integrated into the WiX v4 namespace. Remove the namespace."))
1644
{
1645
element.Name = RequiresRefElementName;
1646
}
1647
1648
if (element.Parent.Name == ProvidesElementName &&
1649
element.Parent.Parent?.Name == ComponentElementName &&
1650
- this.OnError(ConverterTestType.IntegratedDependencyNamespace, element, "The RequiresRef element has been integrated into the WiX v4 namespace. Add the 'Enforce' attribute from the WixDependency.wixext to match v3 runtime behavior."))
1650
+ this.OnInformation(ConverterTestType.IntegratedDependencyNamespace, element, "The RequiresRef element has been integrated into the WiX v4 namespace. Add the 'Enforce' attribute from the WixDependency.wixext to match v3 runtime behavior."))
1651
{
1652
element.Add(new XAttribute(DependencyEnforceAttributeName, "yes"));
1653
}
@@ -1658,7 +1658,7 @@ namespace WixToolset.Converters
1658
var suppressSignatureValidation = element.Attribute("SuppressSignatureValidation");
1659
1660
if (null != suppressSignatureValidation
1661
- && this.OnError(ConverterTestType.BundleSignatureValidationObsolete, element, "The chain package element contains obsolete '{0}' attribute. Signature validation is no longer supported. The attribute will be removed.", suppressSignatureValidation.Name))
1661
+ && this.OnInformation(ConverterTestType.BundleSignatureValidationObsolete, element, "The chain package element contains obsolete '{0}' attribute. Signature validation is no longer supported. The attribute will be removed.", suppressSignatureValidation.Name))
1662
{
1663
suppressSignatureValidation.Remove();
1664
}
@@ -1666,7 +1666,7 @@ namespace WixToolset.Converters
1666
1667
private void ConvertTagElement(XElement element)
1668
{
1669
- if (this.OnError(ConverterTestType.TagElementRenamed, element, "The Tag element has been renamed. Use the 'SoftwareTag' element instead."))
1669
+ if (this.OnInformation(ConverterTestType.TagElementRenamed, element, "The Tag element has been renamed. Use the 'SoftwareTag' element instead."))
1670
{
1671
element.Name = SoftwareTagElementName;
1672
}
@@ -1678,7 +1678,7 @@ namespace WixToolset.Converters
1678
1679
private void ConvertTagRefElement(XElement element)
1680
{
1681
- if (this.OnError(ConverterTestType.TagRefElementRenamed, element, "The TagRef element has been renamed. Use the 'SoftwareTagRef' element instead."))
1681
+ if (this.OnInformation(ConverterTestType.TagRefElementRenamed, element, "The TagRef element has been renamed. Use the 'SoftwareTagRef' element instead."))
1682
{
1683
element.Name = SoftwareTagRefElementName;
1684
}
@@ -1711,7 +1711,7 @@ namespace WixToolset.Converters
1711
private void ConvertCustomActionElement(XElement xCustomAction)
1712
{
1713
var xBinaryKey = xCustomAction.Attribute("BinaryKey");
1714
- if (xBinaryKey != null && this.OnError(ConverterTestType.CustomActionKeysAreNowRefs, xCustomAction, "The CustomAction attributes have been renamed from BinaryKey and FileKey to BinaryRef and FileRef."))
1714
+ if (xBinaryKey != null && this.OnInformation(ConverterTestType.CustomActionKeysAreNowRefs, xCustomAction, "The CustomAction attributes have been renamed from BinaryKey and FileKey to BinaryRef and FileRef."))
1715
{
1716
xCustomAction.SetAttributeValue("BinaryRef", xBinaryKey.Value);
1717
xBinaryKey.Remove();
@@ -1719,7 +1719,7 @@ namespace WixToolset.Converters
1719
}
1720
1721
var xFileKey = xCustomAction.Attribute("FileKey");
1722
- if (xFileKey != null && this.OnError(ConverterTestType.CustomActionKeysAreNowRefs, xCustomAction, "The CustomAction attributes have been renamed from BinaryKey and FileKey to BinaryRef and FileRef."))
1722
+ if (xFileKey != null && this.OnInformation(ConverterTestType.CustomActionKeysAreNowRefs, xCustomAction, "The CustomAction attributes have been renamed from BinaryKey and FileKey to BinaryRef and FileRef."))
1723
{
1724
xCustomAction.SetAttributeValue("FileRef", xFileKey.Value);
1725
xFileKey.Remove();
@@ -1727,7 +1727,7 @@ namespace WixToolset.Converters
1727
1728
if (xBinaryKey?.Value == "WixCA" || xBinaryKey?.Value == "UtilCA")
1729
{
1730
- if (this.OnError(ConverterTestType.WixCABinaryIdRenamed, xCustomAction, "The WixCA custom action DLL Binary table id has been renamed. Use the id 'Wix4UtilCA_X86' instead."))
1730
+ if (this.OnInformation(ConverterTestType.WixCABinaryIdRenamed, xCustomAction, "The WixCA custom action DLL Binary table id has been renamed. Use the id 'Wix4UtilCA_X86' instead."))
1731
{
1732
xBinaryKey.Value = "Wix4UtilCA_X86";
1733
}
@@ -1735,7 +1735,7 @@ namespace WixToolset.Converters
1735
1736
if (xBinaryKey?.Value == "WixCA_x64" || xBinaryKey?.Value == "UtilCA_x64")
1737
{
1738
- if (this.OnError(ConverterTestType.WixCABinaryIdRenamed, xCustomAction, "The WixCA_x64 custom action DLL Binary table id has been renamed. Use the id 'Wix4UtilCA_X64' instead."))
1738
+ if (this.OnInformation(ConverterTestType.WixCABinaryIdRenamed, xCustomAction, "The WixCA_x64 custom action DLL Binary table id has been renamed. Use the id 'Wix4UtilCA_X64' instead."))
1739
{
1740
xBinaryKey.Value = "Wix4UtilCA_X64";
1741
}
@@ -1745,7 +1745,7 @@ namespace WixToolset.Converters
1745
1746
if (xDllEntry?.Value == "CAQuietExec" || xDllEntry?.Value == "CAQuietExec64")
1747
{
1748
- if (this.OnError(ConverterTestType.QuietExecCustomActionsRenamed, xCustomAction, "The CAQuietExec and CAQuietExec64 custom action ids have been renamed. Use the ids 'WixQuietExec' and 'WixQuietExec64' instead."))
1748
+ if (this.OnInformation(ConverterTestType.QuietExecCustomActionsRenamed, xCustomAction, "The CAQuietExec and CAQuietExec64 custom action ids have been renamed. Use the ids 'WixQuietExec' and 'WixQuietExec64' instead."))
1749
{
1750
xDllEntry.Value = xDllEntry.Value.Replace("CAQuietExec", "WixQuietExec");
1751
}
@@ -1755,7 +1755,7 @@ namespace WixToolset.Converters
1755
1756
if (xProperty?.Value == "QtExecCmdLine" || xProperty?.Value == "QtExec64CmdLine")
1757
{
1758
- if (this.OnError(ConverterTestType.QuietExecCustomActionsRenamed, xCustomAction, "The QtExecCmdLine and QtExec64CmdLine property ids have been renamed. Use the ids 'WixQuietExecCmdLine' and 'WixQuietExec64CmdLine' instead."))
1758
+ if (this.OnInformation(ConverterTestType.QuietExecCustomActionsRenamed, xCustomAction, "The QtExecCmdLine and QtExec64CmdLine property ids have been renamed. Use the ids 'WixQuietExecCmdLine' and 'WixQuietExec64CmdLine' instead."))
1759
{
1760
xProperty.Value = xProperty.Value.Replace("QtExec", "WixQuietExec");
1761
}
@@ -1765,7 +1765,7 @@ namespace WixToolset.Converters
1765
1766
if (xScript != null && TryGetInnerText(xCustomAction, out var scriptText))
1767
{
1768
- if (this.OnError(ConverterTestType.InnerTextDeprecated, xCustomAction, "Using {0} element text is deprecated. Extract the text to a file and use the 'ScriptSourceFile' attribute to reference it.", xCustomAction.Name.LocalName))
1768
+ if (this.OnInformation(ConverterTestType.InnerTextDeprecated, xCustomAction, "Using {0} element text is deprecated. Extract the text to a file and use the 'ScriptSourceFile' attribute to reference it.", xCustomAction.Name.LocalName))
1769
{
1770
var scriptFolder = Path.GetDirectoryName(this.SourceFile) ?? String.Empty;
1771
var id = xCustomAction.Attribute("Id")?.Value ?? Guid.NewGuid().ToString("N");
@@ -1789,13 +1789,13 @@ namespace WixToolset.Converters
1789
if (xType == null)
1790
{
1791
if (WasImplicitlyStringTyped(xValue?.Value) &&
1792
- this.OnError(ConverterTestType.AssignVariableTypeFormatted, xVariable, "The \"string\" variable type now denotes a literal string. Use \"formatted\" to keep the previous behavior."))
1792
+ this.OnInformation(ConverterTestType.AssignVariableTypeFormatted, xVariable, "The \"string\" variable type now denotes a literal string. Use \"formatted\" to keep the previous behavior."))
1793
{
1794
xVariable.Add(new XAttribute("Type", "formatted"));
1795
}
1796
}
1797
else if (xType.Value == "string" &&
1798
- this.OnError(ConverterTestType.AssignVariableTypeFormatted, xVariable, "The \"string\" variable type now denotes a literal string. Use \"formatted\" to keep the previous behavior."))
1798
+ this.OnInformation(ConverterTestType.AssignVariableTypeFormatted, xVariable, "The \"string\" variable type now denotes a literal string. Use \"formatted\" to keep the previous behavior."))
1799
{
1800
xType.Value = "formatted";
1801
}
@@ -1808,7 +1808,7 @@ namespace WixToolset.Converters
1808
1809
if (xId.Value == "QtExecCmdTimeout")
1810
{
1811
- this.OnError(ConverterTestType.QtExecCmdTimeoutAmbiguous, xProperty, "QtExecCmdTimeout was previously used for both CAQuietExec and CAQuietExec64. For WixQuietExec, use WixQuietExecCmdTimeout. For WixQuietExec64, use WixQuietExec64CmdTimeout.");
1811
+ this.OnInformation(ConverterTestType.QtExecCmdTimeoutAmbiguous, xProperty, "QtExecCmdTimeout was previously used for both CAQuietExec and CAQuietExec64. For WixQuietExec, use WixQuietExecCmdTimeout. For WixQuietExec64, use WixQuietExec64CmdTimeout.");
1812
}
1813
1814
this.ConvertInnerTextToAttribute(xProperty, "Value");
@@ -1823,7 +1823,7 @@ namespace WixToolset.Converters
1823
var inheritable = element.Parent.Name == CreateFolderElementName;
1824
if (!inheritable)
1825
{
1826
- if (this.OnError(ConverterTestType.AssignPermissionExInheritable, element, "The PermissionEx Inheritable attribute is being set to 'no' to ensure it remains the same as the v3 default."))
1826
+ if (this.OnInformation(ConverterTestType.AssignPermissionExInheritable, element, "The PermissionEx Inheritable attribute is being set to 'no' to ensure it remains the same as the v3 default."))
1827
{
1828
element.Add(new XAttribute("Inheritable", "no"));
1829
}
@@ -1854,7 +1854,7 @@ namespace WixToolset.Converters
1854
/// <returns>The converted element.</returns>
1855
private void ConvertElementWithoutNamespace(XElement element)
1856
{
1857
- if (this.OnError(ConverterTestType.XmlnsMissing, element, "The xmlns attribute is missing. It must be present with a value of '{0}'.", WixNamespace.NamespaceName))
1857
+ if (this.OnInformation(ConverterTestType.XmlnsMissing, element, "The xmlns attribute is missing. It must be present with a value of '{0}'.", WixNamespace.NamespaceName))
1858
{
1859
element.Name = WixNamespace.GetName(element.Name.LocalName);
1860
@@ -1870,7 +1870,7 @@ namespace WixToolset.Converters
1870
private void ConvertInnerTextToAttribute(XElement element, string attributeName)
1871
{
1872
if (TryGetInnerText(element, out var text) &&
1873
- this.OnError(ConverterTestType.InnerTextDeprecated, element, "Using {0} element text is deprecated. Use the '{1}' attribute instead.", element.Name.LocalName, attributeName))
1873
+ this.OnInformation(ConverterTestType.InnerTextDeprecated, element, "Using {0} element text is deprecated. Use the '{1}' attribute instead.", element.Name.LocalName, attributeName))
1874
{
1875
element.Add(new XAttribute(attributeName, text));
1876
RemoveChildren(element);
@@ -1880,7 +1880,7 @@ namespace WixToolset.Converters
1880
void RemoveAttributeIfPresent(XElement element, string attributeName, ConverterTestType type, string format)
1881
{
1882
var xAttribute = element.Attribute(attributeName);
1883
- if (null != xAttribute && this.OnError(type, element, format, element.Name.LocalName, xAttribute.Name))
1883
+ if (null != xAttribute && this.OnInformation(type, element, format, element.Name.LocalName, xAttribute.Name))
1884
{
1885
xAttribute.Remove();
1886
}
@@ -1889,7 +1889,7 @@ namespace WixToolset.Converters
1889
private void RenameWin64ToBitness(XElement element)
1890
{
1891
var win64 = element.Attribute("Win64");
1892
- if (win64 != null && this.OnError(ConverterTestType.Win64AttributeRenamed, element, "The {0} element's Win64 attribute has been renamed. Use the Bitness attribute instead.", element.Name.LocalName))
1892
+ if (win64 != null && this.OnInformation(ConverterTestType.Win64AttributeRenamed, element, "The {0} element's Win64 attribute has been renamed. Use the Bitness attribute instead.", element.Name.LocalName))
1893
{
1894
var value = this.UpdateWin64ValueToBitnessValue(win64);
1895
element.Add(new XAttribute("Bitness", value));
@@ -1917,7 +1917,7 @@ namespace WixToolset.Converters
1917
}
1918
1919
if (!String.IsNullOrEmpty(replacement) &&
1920
- this.OnError(ConverterTestType.BundlePackageCacheAttributeValueObsolete, element, "The chain package element 'Cache' attribute contains obsolete '{0}' value. The value should be '{1}' instead.", cacheValue, replacement))
1920
+ this.OnInformation(ConverterTestType.BundlePackageCacheAttributeValueObsolete, element, "The chain package element 'Cache' attribute contains obsolete '{0}' value. The value should be '{1}' instead.", cacheValue, replacement))
1921
{
1922
cacheAttribute.SetValue(replacement);
1923
}
@@ -2068,7 +2068,7 @@ namespace WixToolset.Converters
2068
foreach (var declaration in declarations)
2069
{
2070
if (namespaces.Contains(declaration.Value) &&
2071
- this.OnError(ConverterTestType.RemoveUnusedNamespaces, declaration, "The namespace '{0}' is not used. Remove unused namespaces.", declaration.Value))
2071
+ this.OnInformation(ConverterTestType.RemoveUnusedNamespaces, declaration, "The namespace '{0}' is not used. Remove unused namespaces.", declaration.Value))
2072
{
2073
declaration.Remove();
2074
}
@@ -2093,14 +2093,55 @@ namespace WixToolset.Converters
2093
return false;
2094
}
2095
2096
- // Increase the error count.
2097
- this.Errors++;
2096
+ // Increase the message count.
2097
+ this.Messages++;
2098
2099
var sourceLine = (null == node) ? new SourceLineNumber(this.SourceFile ?? "wix.exe") : new SourceLineNumber(this.SourceFile, ((IXmlLineInfo)node).LineNumber);
2100
var warning = this.ErrorsAsWarnings.Contains(converterTestType);
2101
- var display = String.Format(CultureInfo.CurrentCulture, message, args);
2101
+
2102
+ var msg = new Message(
2103
+ sourceLine,
2104
+ warning ? MessageLevel.Warning : MessageLevel.Error,
2105
+ (int)converterTestType,
2106
+ "{0} ({1})",
2107
+ String.Format(CultureInfo.CurrentCulture, message, args),
2108
+ converterTestType.ToString());
2109
+
2110
+ this.Messaging.Write(msg);
2111
+
2112
+ return true;
2113
+ }
2114
+
2115
+ /// <summary>
2116
+ /// Output an information message to the console.
2117
+ /// </summary>
2118
+ /// <param name="converterTestType">The type of converter test.</param>
2119
+ /// <param name="node">The node that caused the error.</param>
2120
+ /// <param name="message">Detailed error message.</param>
2121
+ /// <param name="args">Additional formatted string arguments.</param>
2122
+ /// <returns>Returns true indicating that action should be taken on this error, and false if it should be ignored.</returns>
2123
+ private bool OnInformation(ConverterTestType converterTestType, XObject node, string message, params object[] args)
2124
+ {
2125
+ // Ignore the error if explicitly ignored or outside the range of the current operation.
2126
+ if (this.IgnoreErrors.Contains(converterTestType) ||
2127
+ (this.Operation == ConvertOperation.Convert && converterTestType < ConverterTestType.EndIgnoreInConvert) ||
2128
+ (this.Operation == ConvertOperation.Format && converterTestType > ConverterTestType.BeginIgnoreInFormat))
2129
+ {
2130
+ return false;
2131
+ }
2132
+
2133
+ // Increase the message count.
2134
+ this.Messages++;
2135
+
2136
+ var sourceLine = (null == node) ? new SourceLineNumber(this.SourceFile ?? "wix.exe") : new SourceLineNumber(this.SourceFile, ((IXmlLineInfo)node).LineNumber);
2137
2103
- var msg = new Message(sourceLine, warning ? MessageLevel.Warning : MessageLevel.Error, (int)converterTestType, "{0} ({1})", display, converterTestType.ToString());
2138
+ var msg = new Message(
2139
+ sourceLine,
2140
+ MessageLevel.Information,
2141
+ (int)converterTestType,
2142
+ "[Converted] {0} ({1})",
2143
+ String.Format(CultureInfo.CurrentCulture, message, args),
2144
+ converterTestType.ToString());
2145
2146
this.Messaging.Write(msg);
2147