aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2022-12-22 16:39:29 -0800
committerRob Mensching <rob@firegiant.com>2022-12-22 17:25:11 -0800
commit156ccd9db15eafe6b4fef72097dfa04337599f91 (patch)
tree0263cdc56dffa8e181c5221d73cae1e4b10ae58b
parent8aafcc72550d89cc43dfcb81012abe8576709660 (diff)
downloadwix-156ccd9db15eafe6b4fef72097dfa04337599f91.tar.gz
wix-156ccd9db15eafe6b4fef72097dfa04337599f91.tar.bz2
wix-156ccd9db15eafe6b4fef72097dfa04337599f91.zip
Fix RegistrySymbol creation helper for non-string types
Fixes 7108
-rw-r--r--src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs17
-rw-r--r--src/ext/PowerShell/wixext/PSCompiler.cs22
-rw-r--r--src/ext/Util/wixext/UtilCompiler.cs30
-rw-r--r--src/wix/WixToolset.Core/Compiler.cs72
-rw-r--r--src/wix/WixToolset.Core/CompilerCore.cs4
-rw-r--r--src/wix/WixToolset.Core/Compiler_Dependency.cs6
-rw-r--r--src/wix/WixToolset.Core/Compiler_Package.cs26
-rw-r--r--src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs15
8 files changed, 103 insertions, 89 deletions
diff --git a/src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs b/src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs
index 567b623c..3c20c14b 100644
--- a/src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs
+++ b/src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs
@@ -104,8 +104,21 @@ namespace WixToolset.Extensibility.Services
104 /// <param name="name">The registry entry name.</param> 104 /// <param name="name">The registry entry name.</param>
105 /// <param name="value">The registry entry value.</param> 105 /// <param name="value">The registry entry value.</param>
106 /// <param name="componentId">The component which will control installation/uninstallation of the registry entry.</param> 106 /// <param name="componentId">The component which will control installation/uninstallation of the registry entry.</param>
107 /// <param name="escapeLeadingHash">If true, "escape" leading '#' characters so the value is written as a REG_SZ.</param> 107 /// <param name="valueType">The registry value type. Default is string.</param>
108 Identifier CreateRegistrySymbol(IntermediateSection section, SourceLineNumber sourceLineNumbers, RegistryRootType root, string key, string name, string value, string componentId, bool escapeLeadingHash); 108 /// <param name="valueAction">The way to apply the registry value. Default is write.</param>
109 Identifier CreateRegistrySymbol(IntermediateSection section, SourceLineNumber sourceLineNumbers, RegistryRootType root, string key, string name, string value, string componentId, RegistryValueType valueType = RegistryValueType.String, RegistryValueActionType valueAction = RegistryValueActionType.Write);
110
111 /// <summary>
112 /// Creates a numeric Registry symbol in the active section.
113 /// </summary>
114 /// <param name="section">Active section.</param>
115 /// <param name="sourceLineNumbers">Source and line number of the current symbol.</param>
116 /// <param name="root">The registry entry root.</param>
117 /// <param name="key">The registry entry key.</param>
118 /// <param name="name">The registry entry name.</param>
119 /// <param name="value">The numeric registry entry value.</param>
120 /// <param name="componentId">The component which will control installation/uninstallation of the registry entry.</param>
121 Identifier CreateRegistrySymbol(IntermediateSection section, SourceLineNumber sourceLineNumbers, RegistryRootType root, string key, string name, int value, string componentId);
109 122
110 /// <summary> 123 /// <summary>
111 /// Create a WixSimpleReference symbol in the active section. 124 /// Create a WixSimpleReference symbol in the active section.
diff --git a/src/ext/PowerShell/wixext/PSCompiler.cs b/src/ext/PowerShell/wixext/PSCompiler.cs
index 37591282..7cb4149e 100644
--- a/src/ext/PowerShell/wixext/PSCompiler.cs
+++ b/src/ext/PowerShell/wixext/PSCompiler.cs
@@ -185,46 +185,46 @@ namespace WixToolset.PowerShell
185 var registryRoot = RegistryRootType.LocalMachine; // HKLM 185 var registryRoot = RegistryRootType.LocalMachine; // HKLM
186 var registryKey = String.Format(CultureInfo.InvariantCulture, KeyFormat, major, id); 186 var registryKey = String.Format(CultureInfo.InvariantCulture, KeyFormat, major, id);
187 187
188 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "ApplicationBase", String.Format(CultureInfo.InvariantCulture, "[${0}]", componentId), componentId, false); 188 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "ApplicationBase", String.Format(CultureInfo.InvariantCulture, "[${0}]", componentId), componentId);
189 189
190 // set the assembly name automatically when binding. 190 // set the assembly name automatically when binding.
191 // processorArchitecture is not handled correctly by PowerShell v1.0 191 // processorArchitecture is not handled correctly by PowerShell v1.0
192 // so format the assembly name explicitly. 192 // so format the assembly name explicitly.
193 var assemblyName = String.Format(CultureInfo.InvariantCulture, "!(bind.assemblyName.{0}), Version=!(bind.assemblyVersion.{0}), Culture=!(bind.assemblyCulture.{0}), PublicKeyToken=!(bind.assemblyPublicKeyToken.{0})", fileId); 193 var assemblyName = String.Format(CultureInfo.InvariantCulture, "!(bind.assemblyName.{0}), Version=!(bind.assemblyVersion.{0}), Culture=!(bind.assemblyCulture.{0}), PublicKeyToken=!(bind.assemblyPublicKeyToken.{0})", fileId);
194 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "AssemblyName", assemblyName, componentId, false); 194 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "AssemblyName", assemblyName, componentId);
195 195
196 if (null != customSnapInType) 196 if (null != customSnapInType)
197 { 197 {
198 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "CustomPSSnapInType", customSnapInType, componentId, false); 198 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "CustomPSSnapInType", customSnapInType, componentId);
199 } 199 }
200 200
201 if (null != description) 201 if (null != description)
202 { 202 {
203 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "Description", description, componentId, false); 203 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "Description", description, componentId);
204 } 204 }
205 205
206 if (null != descriptionIndirect) 206 if (null != descriptionIndirect)
207 { 207 {
208 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "DescriptionIndirect", descriptionIndirect, componentId, false); 208 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "DescriptionIndirect", descriptionIndirect, componentId);
209 } 209 }
210 210
211 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "ModuleName", String.Format(CultureInfo.InvariantCulture, "[#{0}]", fileId), componentId, false); 211 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "ModuleName", String.Format(CultureInfo.InvariantCulture, "[#{0}]", fileId), componentId);
212 212
213 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "PowerShellVersion", requiredPowerShellVersion.ToString(2), componentId, false); 213 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "PowerShellVersion", requiredPowerShellVersion.ToString(2), componentId);
214 214
215 if (null != vendor) 215 if (null != vendor)
216 { 216 {
217 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "Vendor", vendor, componentId, false); 217 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "Vendor", vendor, componentId);
218 } 218 }
219 219
220 if (null != vendorIndirect) 220 if (null != vendorIndirect)
221 { 221 {
222 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "VendorIndirect", vendorIndirect, componentId, false); 222 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "VendorIndirect", vendorIndirect, componentId);
223 } 223 }
224 224
225 if (null != version) 225 if (null != version)
226 { 226 {
227 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "Version", version, componentId, false); 227 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, "Version", version, componentId);
228 } 228 }
229 } 229 }
230 230
@@ -279,7 +279,7 @@ namespace WixToolset.PowerShell
279 var registryKey = String.Format(CultureInfo.InvariantCulture, KeyFormat, String.Format(CultureInfo.InvariantCulture, "!(wix.{0}_{1})", VarPrefix, snapIn), snapIn); 279 var registryKey = String.Format(CultureInfo.InvariantCulture, KeyFormat, String.Format(CultureInfo.InvariantCulture, "!(wix.{0}_{1})", VarPrefix, snapIn), snapIn);
280 280
281 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.File, fileId); 281 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.File, fileId);
282 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, valueName, String.Format(CultureInfo.InvariantCulture, "[~][#{0}]", fileId), componentId, false); 282 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, registryRoot, registryKey, valueName, String.Format(CultureInfo.InvariantCulture, "[#{0}]", fileId), componentId, RegistryValueType.MultiString, RegistryValueActionType.Append);
283 } 283 }
284 } 284 }
285} 285}
diff --git a/src/ext/Util/wixext/UtilCompiler.cs b/src/ext/Util/wixext/UtilCompiler.cs
index 96b2ee0a..c2ae5c94 100644
--- a/src/ext/Util/wixext/UtilCompiler.cs
+++ b/src/ext/Util/wixext/UtilCompiler.cs
@@ -673,7 +673,7 @@ namespace WixToolset.Util
673 var categoryCount = CompilerConstants.IntegerNotSet; 673 var categoryCount = CompilerConstants.IntegerNotSet;
674 string eventMessageFile = null; 674 string eventMessageFile = null;
675 string parameterMessageFile = null; 675 string parameterMessageFile = null;
676 int typesSupported = 0; 676 var typesSupported = 0;
677 var isKeyPath = false; 677 var isKeyPath = false;
678 678
679 foreach (var attrib in element.Attributes()) 679 foreach (var attrib in element.Attributes())
@@ -776,26 +776,26 @@ namespace WixToolset.Util
776 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); 776 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
777 777
778 string eventSourceKey = $@"SYSTEM\CurrentControlSet\Services\EventLog\{logName}\{sourceName}"; 778 string eventSourceKey = $@"SYSTEM\CurrentControlSet\Services\EventLog\{logName}\{sourceName}";
779 var id = this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, eventSourceKey, "EventMessageFile", String.Concat("#%", eventMessageFile), componentId, false); 779 var id = this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, eventSourceKey, "EventMessageFile", eventMessageFile, componentId, RegistryValueType.Expandable);
780 780
781 if (null != categoryMessageFile) 781 if (null != categoryMessageFile)
782 { 782 {
783 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, eventSourceKey, "CategoryMessageFile", String.Concat("#%", categoryMessageFile), componentId, false); 783 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, eventSourceKey, "CategoryMessageFile", categoryMessageFile, componentId, RegistryValueType.Expandable);
784 } 784 }
785 785
786 if (CompilerConstants.IntegerNotSet != categoryCount) 786 if (CompilerConstants.IntegerNotSet != categoryCount)
787 { 787 {
788 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, eventSourceKey, "CategoryCount", String.Concat("#", categoryCount), componentId, false); 788 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, eventSourceKey, "CategoryCount", categoryCount, componentId);
789 } 789 }
790 790
791 if (null != parameterMessageFile) 791 if (null != parameterMessageFile)
792 { 792 {
793 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, eventSourceKey, "ParameterMessageFile", String.Concat("#%", parameterMessageFile), componentId, false); 793 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, eventSourceKey, "ParameterMessageFile", parameterMessageFile, componentId, RegistryValueType.Expandable);
794 } 794 }
795 795
796 if (0 != typesSupported) 796 if (0 != typesSupported)
797 { 797 {
798 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, eventSourceKey, "TypesSupported", String.Concat("#", typesSupported), componentId, false); 798 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, eventSourceKey, "TypesSupported", typesSupported, componentId);
799 } 799 }
800 800
801 var componentKeyPath = this.CreateComponentKeyPath(); 801 var componentKeyPath = this.CreateComponentKeyPath();
@@ -1746,15 +1746,15 @@ namespace WixToolset.Util
1746 var linkageKey = String.Format(@"SYSTEM\CurrentControlSet\Services\{0}\Linkage", escapedName); 1746 var linkageKey = String.Format(@"SYSTEM\CurrentControlSet\Services\{0}\Linkage", escapedName);
1747 var performanceKey = String.Format(@"SYSTEM\CurrentControlSet\Services\{0}\Performance", escapedName); 1747 var performanceKey = String.Format(@"SYSTEM\CurrentControlSet\Services\{0}\Performance", escapedName);
1748 1748
1749 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, linkageKey, "Export", escapedName, componentId, false); 1749 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, linkageKey, "Export", escapedName, componentId);
1750 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "-", null, componentId, false); 1750 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "-", null, componentId);
1751 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "Library", library, componentId, false); 1751 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "Library", library, componentId);
1752 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "Open", openEntryPoint, componentId, false); 1752 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "Open", openEntryPoint, componentId);
1753 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "Collect", collectEntryPoint, componentId, false); 1753 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "Collect", collectEntryPoint, componentId);
1754 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "Close", closeEntryPoint, componentId, false); 1754 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "Close", closeEntryPoint, componentId);
1755 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "IsMultiInstance", YesNoType.Yes == multiInstance ? "#1" : "#0", componentId, false); 1755 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "IsMultiInstance", YesNoType.Yes == multiInstance ? 1 : 0, componentId);
1756 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "Counter Names", sbCounterNames.ToString(), componentId, false); 1756 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "Counter Names", sbCounterNames.ToString(), componentId, RegistryValueType.MultiString);
1757 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "Counter Types", sbCounterTypes.ToString(), componentId, false); 1757 this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, RegistryRootType.LocalMachine, performanceKey, "Counter Types", sbCounterTypes.ToString(), componentId, RegistryValueType.MultiString);
1758 } 1758 }
1759 1759
1760 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4InstallPerfCounterData", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); 1760 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4InstallPerfCounterData", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64);
diff --git a/src/wix/WixToolset.Core/Compiler.cs b/src/wix/WixToolset.Core/Compiler.cs
index 60d4f10c..df0020b5 100644
--- a/src/wix/WixToolset.Core/Compiler.cs
+++ b/src/wix/WixToolset.Core/Compiler.cs
@@ -436,7 +436,7 @@ namespace WixToolset.Core
436 /// <param name="componentId">Identifier of parent component.</param> 436 /// <param name="componentId">Identifier of parent component.</param>
437 private void RegisterImplementedCategories(SourceLineNumber sourceLineNumbers, string categoryId, string classId, string componentId) 437 private void RegisterImplementedCategories(SourceLineNumber sourceLineNumbers, string categoryId, string classId, string componentId)
438 { 438 {
439 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\Implemented Categories\\", categoryId), "*", null, componentId); 439 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\Implemented Categories\\", categoryId), "*", null, componentId);
440 } 440 }
441 441
442 /// <summary> 442 /// <summary>
@@ -570,41 +570,41 @@ namespace WixToolset.Core
570 { 570 {
571 if (null != description) 571 if (null != description)
572 { 572 {
573 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), null, description, componentId); 573 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), null, description, componentId);
574 } 574 }
575 else 575 else
576 { 576 {
577 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "+", null, componentId); 577 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "+", null, componentId);
578 } 578 }
579 579
580 if (null != remoteServerName) 580 if (null != remoteServerName)
581 { 581 {
582 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "RemoteServerName", remoteServerName, componentId); 582 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "RemoteServerName", remoteServerName, componentId);
583 } 583 }
584 584
585 if (null != localService) 585 if (null != localService)
586 { 586 {
587 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "LocalService", localService, componentId); 587 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "LocalService", localService, componentId);
588 } 588 }
589 589
590 if (null != serviceParameters) 590 if (null != serviceParameters)
591 { 591 {
592 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "ServiceParameters", serviceParameters, componentId); 592 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "ServiceParameters", serviceParameters, componentId);
593 } 593 }
594 594
595 if (null != dllSurrogate) 595 if (null != dllSurrogate)
596 { 596 {
597 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "DllSurrogate", dllSurrogate, componentId); 597 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "DllSurrogate", dllSurrogate, componentId);
598 } 598 }
599 599
600 if (true == activateAtStorage) 600 if (true == activateAtStorage)
601 { 601 {
602 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "ActivateAtStorage", "Y", componentId); 602 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "ActivateAtStorage", "Y", componentId);
603 } 603 }
604 604
605 if (true == runAsInteractiveUser) 605 if (true == runAsInteractiveUser)
606 { 606 {
607 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "RunAs", "Interactive User", componentId); 607 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "RunAs", "Interactive User", componentId);
608 } 608 }
609 } 609 }
610 } 610 }
@@ -1202,7 +1202,7 @@ namespace WixToolset.Core
1202 else if (YesNoType.No == advertise) 1202 else if (YesNoType.No == advertise)
1203 { 1203 {
1204 var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); 1204 var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
1205 this.Core.CreateRegistryRow(childSourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("FileType\\", classId, "\\", fileTypeMaskIndex.ToString()), String.Empty, this.ParseFileTypeMaskElement(child), componentId); 1205 this.Core.CreateRegistryStringSymbol(childSourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("FileType\\", classId, "\\", fileTypeMaskIndex.ToString()), String.Empty, this.ParseFileTypeMaskElement(child), componentId);
1206 fileTypeMaskIndex++; 1206 fileTypeMaskIndex++;
1207 } 1207 }
1208 break; 1208 break;
@@ -1359,7 +1359,7 @@ namespace WixToolset.Core
1359 this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Context", context, "InprocServer", "InprocServer32", "LocalServer", "LocalServer32")); 1359 this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Context", context, "InprocServer", "InprocServer32", "LocalServer", "LocalServer32"));
1360 } 1360 }
1361 1361
1362 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\", context), String.Empty, formattedContextString, componentId); // ClassId context 1362 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\", context), String.Empty, formattedContextString, componentId); // ClassId context
1363 1363
1364 if (null != icon) // ClassId default icon 1364 if (null != icon) // ClassId default icon
1365 { 1365 {
@@ -1371,18 +1371,18 @@ namespace WixToolset.Core
1371 { 1371 {
1372 icon = String.Concat(icon, ",", iconIndex); 1372 icon = String.Concat(icon, ",", iconIndex);
1373 } 1373 }
1374 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\DefaultIcon"), String.Empty, icon, componentId); 1374 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\DefaultIcon"), String.Empty, icon, componentId);
1375 } 1375 }
1376 } 1376 }
1377 1377
1378 if (null != parentAppId) // ClassId AppId (must be specified via nesting, not with the AppId attribute) 1378 if (null != parentAppId) // ClassId AppId (must be specified via nesting, not with the AppId attribute)
1379 { 1379 {
1380 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId), "AppID", parentAppId, componentId); 1380 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId), "AppID", parentAppId, componentId);
1381 } 1381 }
1382 1382
1383 if (null != description) // ClassId description 1383 if (null != description) // ClassId description
1384 { 1384 {
1385 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId), String.Empty, description, componentId); 1385 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId), String.Empty, description, componentId);
1386 } 1386 }
1387 1387
1388 if (null != defaultInprocHandler) 1388 if (null != defaultInprocHandler)
@@ -1390,17 +1390,17 @@ namespace WixToolset.Core
1390 switch (defaultInprocHandler) // ClassId Default Inproc Handler 1390 switch (defaultInprocHandler) // ClassId Default Inproc Handler
1391 { 1391 {
1392 case "1": 1392 case "1":
1393 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler"), String.Empty, "ole2.dll", componentId); 1393 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler"), String.Empty, "ole2.dll", componentId);
1394 break; 1394 break;
1395 case "2": 1395 case "2":
1396 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler32"), String.Empty, "ole32.dll", componentId); 1396 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler32"), String.Empty, "ole32.dll", componentId);
1397 break; 1397 break;
1398 case "3": 1398 case "3":
1399 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler"), String.Empty, "ole2.dll", componentId); 1399 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler"), String.Empty, "ole2.dll", componentId);
1400 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler32"), String.Empty, "ole32.dll", componentId); 1400 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler32"), String.Empty, "ole32.dll", componentId);
1401 break; 1401 break;
1402 default: 1402 default:
1403 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler32"), String.Empty, defaultInprocHandler, componentId); 1403 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler32"), String.Empty, defaultInprocHandler, componentId);
1404 break; 1404 break;
1405 } 1405 }
1406 } 1406 }
@@ -1418,36 +1418,36 @@ namespace WixToolset.Core
1418 // add a threading model for each context in the class 1418 // add a threading model for each context in the class
1419 foreach (var context in contexts) 1419 foreach (var context in contexts)
1420 { 1420 {
1421 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\", context), "ThreadingModel", threadingModel, componentId); 1421 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\", context), "ThreadingModel", threadingModel, componentId);
1422 } 1422 }
1423 } 1423 }
1424 1424
1425 if (null != typeLibId) 1425 if (null != typeLibId)
1426 { 1426 {
1427 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\TypeLib"), null, typeLibId, componentId); 1427 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\TypeLib"), null, typeLibId, componentId);
1428 } 1428 }
1429 1429
1430 if (null != version) 1430 if (null != version)
1431 { 1431 {
1432 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\Version"), null, version, componentId); 1432 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\Version"), null, version, componentId);
1433 } 1433 }
1434 1434
1435 if (null != insertable) 1435 if (null != insertable)
1436 { 1436 {
1437 // Add "*" for name so that any subkeys (shouldn't be any) are removed on uninstall. 1437 // Add "*" for name so that any subkeys (shouldn't be any) are removed on uninstall.
1438 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\", insertable), "*", null, componentId); 1438 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\", insertable), "*", null, componentId);
1439 } 1439 }
1440 1440
1441 if (control) 1441 if (control)
1442 { 1442 {
1443 // Add "*" for name so that any subkeys (shouldn't be any) are removed on uninstall. 1443 // Add "*" for name so that any subkeys (shouldn't be any) are removed on uninstall.
1444 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\Control"), "*", null, componentId); 1444 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\Control"), "*", null, componentId);
1445 } 1445 }
1446 1446
1447 if (programmable) 1447 if (programmable)
1448 { 1448 {
1449 // Add "*" for name so that any subkeys (shouldn't be any) are removed on uninstall. 1449 // Add "*" for name so that any subkeys (shouldn't be any) are removed on uninstall.
1450 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\Programmable"), "*", null, componentId); 1450 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\Programmable"), "*", null, componentId);
1451 } 1451 }
1452 1452
1453 if (safeForInit) 1453 if (safeForInit)
@@ -1529,34 +1529,34 @@ namespace WixToolset.Core
1529 1529
1530 this.Core.ParseForExtensionElements(node); 1530 this.Core.ParseForExtensionElements(node);
1531 1531
1532 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("Interface\\", interfaceId), null, name, componentId); 1532 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("Interface\\", interfaceId), null, name, componentId);
1533 if (null != typeLibId) 1533 if (null != typeLibId)
1534 { 1534 {
1535 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("Interface\\", interfaceId, "\\TypeLib"), null, typeLibId, componentId); 1535 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("Interface\\", interfaceId, "\\TypeLib"), null, typeLibId, componentId);
1536 if (versioned) 1536 if (versioned)
1537 { 1537 {
1538 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("Interface\\", interfaceId, "\\TypeLib"), "Version", typelibVersion, componentId); 1538 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("Interface\\", interfaceId, "\\TypeLib"), "Version", typelibVersion, componentId);
1539 } 1539 }
1540 } 1540 }
1541 1541
1542 if (null != baseInterface) 1542 if (null != baseInterface)
1543 { 1543 {
1544 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("Interface\\", interfaceId, "\\BaseInterface"), null, baseInterface, componentId); 1544 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("Interface\\", interfaceId, "\\BaseInterface"), null, baseInterface, componentId);
1545 } 1545 }
1546 1546
1547 if (CompilerConstants.IntegerNotSet != numMethods) 1547 if (CompilerConstants.IntegerNotSet != numMethods)
1548 { 1548 {
1549 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("Interface\\", interfaceId, "\\NumMethods"), null, numMethods.ToString(), componentId); 1549 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("Interface\\", interfaceId, "\\NumMethods"), null, numMethods.ToString(), componentId);
1550 } 1550 }
1551 1551
1552 if (null != proxyId) 1552 if (null != proxyId)
1553 { 1553 {
1554 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("Interface\\", interfaceId, "\\ProxyStubClsid"), null, proxyId, componentId); 1554 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("Interface\\", interfaceId, "\\ProxyStubClsid"), null, proxyId, componentId);
1555 } 1555 }
1556 1556
1557 if (null != proxyId32) 1557 if (null != proxyId32)
1558 { 1558 {
1559 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("Interface\\", interfaceId, "\\ProxyStubClsid32"), null, proxyId32, componentId); 1559 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("Interface\\", interfaceId, "\\ProxyStubClsid32"), null, proxyId32, componentId);
1560 } 1560 }
1561 } 1561 }
1562 1562
@@ -4990,10 +4990,10 @@ namespace WixToolset.Core
4990 } 4990 }
4991 else if (YesNoType.No == advertise) 4991 else if (YesNoType.No == advertise)
4992 { 4992 {
4993 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat(".", extension), String.Empty, progId, componentId); // Extension 4993 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat(".", extension), String.Empty, progId, componentId); // Extension
4994 if (null != mime) 4994 if (null != mime)
4995 { 4995 {
4996 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat(".", extension), "Content Type", mime, componentId); // Extension's MIME ContentType 4996 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat(".", extension), "Content Type", mime, componentId); // Extension's MIME ContentType
4997 } 4997 }
4998 } 4998 }
4999 } 4999 }
@@ -7393,10 +7393,10 @@ namespace WixToolset.Core
7393 this.Core.Write(ErrorMessages.CannotDefaultMismatchedAdvertiseStates(sourceLineNumbers)); 7393 this.Core.Write(ErrorMessages.CannotDefaultMismatchedAdvertiseStates(sourceLineNumbers));
7394 } 7394 }
7395 7395
7396 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("MIME\\Database\\Content Type\\", contentType), "Extension", String.Concat(".", extension), componentId); 7396 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("MIME\\Database\\Content Type\\", contentType), "Extension", String.Concat(".", extension), componentId);
7397 if (null != classId) 7397 if (null != classId)
7398 { 7398 {
7399 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("MIME\\Database\\Content Type\\", contentType), "CLSID", classId, componentId); 7399 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("MIME\\Database\\Content Type\\", contentType), "CLSID", classId, componentId);
7400 } 7400 }
7401 } 7401 }
7402 7402
diff --git a/src/wix/WixToolset.Core/CompilerCore.cs b/src/wix/WixToolset.Core/CompilerCore.cs
index e02162e3..b01f8670 100644
--- a/src/wix/WixToolset.Core/CompilerCore.cs
+++ b/src/wix/WixToolset.Core/CompilerCore.cs
@@ -301,9 +301,9 @@ namespace WixToolset.Core
301 /// <param name="name">The registry entry name.</param> 301 /// <param name="name">The registry entry name.</param>
302 /// <param name="value">The registry entry value.</param> 302 /// <param name="value">The registry entry value.</param>
303 /// <param name="componentId">The component which will control installation/uninstallation of the registry entry.</param> 303 /// <param name="componentId">The component which will control installation/uninstallation of the registry entry.</param>
304 public Identifier CreateRegistryRow(SourceLineNumber sourceLineNumbers, RegistryRootType root, string key, string name, string value, string componentId) 304 public Identifier CreateRegistryStringSymbol(SourceLineNumber sourceLineNumbers, RegistryRootType root, string key, string name, string value, string componentId)
305 { 305 {
306 return this.parseHelper.CreateRegistrySymbol(this.ActiveSection, sourceLineNumbers, root, key, name, value, componentId, true); 306 return this.parseHelper.CreateRegistrySymbol(this.ActiveSection, sourceLineNumbers, root, key, name, value, componentId);
307 } 307 }
308 308
309 /// <summary> 309 /// <summary>
diff --git a/src/wix/WixToolset.Core/Compiler_Dependency.cs b/src/wix/WixToolset.Core/Compiler_Dependency.cs
index 5cc4bf77..e73324cb 100644
--- a/src/wix/WixToolset.Core/Compiler_Dependency.cs
+++ b/src/wix/WixToolset.Core/Compiler_Dependency.cs
@@ -208,13 +208,13 @@ namespace WixToolset.Core
208 var root = RegistryRootType.MachineUser; 208 var root = RegistryRootType.MachineUser;
209 209
210 var value = "[ProductCode]"; 210 var value = "[ProductCode]";
211 this.Core.CreateRegistryRow(sourceLineNumbers, root, keyProvides, null, value, parentId); 211 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, root, keyProvides, null, value, parentId);
212 212
213 value = !String.IsNullOrEmpty(version) ? version : "[ProductVersion]"; 213 value = !String.IsNullOrEmpty(version) ? version : "[ProductVersion]";
214 var versionRegistrySymbol = this.Core.CreateRegistryRow(sourceLineNumbers, root, keyProvides, "Version", value, parentId); 214 var versionRegistrySymbol = this.Core.CreateRegistryStringSymbol(sourceLineNumbers, root, keyProvides, "Version", value, parentId);
215 215
216 value = !String.IsNullOrEmpty(displayName) ? displayName : "[ProductName]"; 216 value = !String.IsNullOrEmpty(displayName) ? displayName : "[ProductName]";
217 this.Core.CreateRegistryRow(sourceLineNumbers, root, keyProvides, "DisplayName", value, parentId); 217 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, root, keyProvides, "DisplayName", value, parentId);
218 218
219 // Use the Version registry value and use that as a potential key path. 219 // Use the Version registry value and use that as a potential key path.
220 possibleKeyPath = versionRegistrySymbol.Id; 220 possibleKeyPath = versionRegistrySymbol.Id;
diff --git a/src/wix/WixToolset.Core/Compiler_Package.cs b/src/wix/WixToolset.Core/Compiler_Package.cs
index 3c9e6d6a..e59c394a 100644
--- a/src/wix/WixToolset.Core/Compiler_Package.cs
+++ b/src/wix/WixToolset.Core/Compiler_Package.cs
@@ -1317,24 +1317,24 @@ namespace WixToolset.Core
1317 } 1317 }
1318 else if (YesNoType.No == advertise) 1318 else if (YesNoType.No == advertise)
1319 { 1319 {
1320 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, progId, String.Empty, description, componentId); 1320 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, progId, String.Empty, description, componentId);
1321 if (null != classId) 1321 if (null != classId)
1322 { 1322 {
1323 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat(progId, "\\CLSID"), String.Empty, classId, componentId); 1323 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat(progId, "\\CLSID"), String.Empty, classId, componentId);
1324 if (null != parent) // if this is a version independent ProgId 1324 if (null != parent) // if this is a version independent ProgId
1325 { 1325 {
1326 if (YesNoType.Yes == firstProgIdForClass) 1326 if (YesNoType.Yes == firstProgIdForClass)
1327 { 1327 {
1328 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\VersionIndependentProgID"), String.Empty, progId, componentId); 1328 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\VersionIndependentProgID"), String.Empty, progId, componentId);
1329 } 1329 }
1330 1330
1331 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat(progId, "\\CurVer"), String.Empty, parent, componentId); 1331 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat(progId, "\\CurVer"), String.Empty, parent, componentId);
1332 } 1332 }
1333 else 1333 else
1334 { 1334 {
1335 if (YesNoType.Yes == firstProgIdForClass) 1335 if (YesNoType.Yes == firstProgIdForClass)
1336 { 1336 {
1337 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\ProgID"), String.Empty, progId, componentId); 1337 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("CLSID\\", classId, "\\ProgID"), String.Empty, progId, componentId);
1338 } 1338 }
1339 } 1339 }
1340 } 1340 }
@@ -1350,13 +1350,13 @@ namespace WixToolset.Core
1350 icon = String.Concat(icon, ",", iconIndex); 1350 icon = String.Concat(icon, ",", iconIndex);
1351 } 1351 }
1352 1352
1353 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat(progId, "\\DefaultIcon"), String.Empty, icon, componentId); 1353 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat(progId, "\\DefaultIcon"), String.Empty, icon, componentId);
1354 } 1354 }
1355 } 1355 }
1356 1356
1357 if (null != noOpen) 1357 if (null != noOpen)
1358 { 1358 {
1359 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, progId, "NoOpen", noOpen, componentId); // ProgId NoOpen name 1359 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, progId, "NoOpen", noOpen, componentId); // ProgId NoOpen name
1360 } 1360 }
1361 1361
1362 // raise an error for an orphaned ProgId 1362 // raise an error for an orphaned ProgId
@@ -4572,7 +4572,7 @@ namespace WixToolset.Core
4572 } 4572 }
4573 4573
4574 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion], (Default) = [Description] 4574 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion], (Default) = [Description]
4575 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}", id, registryVersion), null, description, componentId); 4575 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}", id, registryVersion), null, description, componentId);
4576 4576
4577 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion]\[Language]\[win16|win32|win64], (Default) = [TypeLibPath]\[ResourceId] 4577 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion]\[Language]\[win16|win32|win64], (Default) = [TypeLibPath]\[ResourceId]
4578 var path = String.Concat("[#", fileServer, "]"); 4578 var path = String.Concat("[#", fileServer, "]");
@@ -4580,15 +4580,15 @@ namespace WixToolset.Core
4580 { 4580 {
4581 path = String.Concat(path, Path.DirectorySeparatorChar, resourceId.ToString(CultureInfo.InvariantCulture.NumberFormat)); 4581 path = String.Concat(path, Path.DirectorySeparatorChar, resourceId.ToString(CultureInfo.InvariantCulture.NumberFormat));
4582 } 4582 }
4583 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\{2}\{3}", id, registryVersion, language, (win64Component ? "win64" : "win32")), null, path, componentId); 4583 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\{2}\{3}", id, registryVersion, language, (win64Component ? "win64" : "win32")), null, path, componentId);
4584 4584
4585 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion]\FLAGS, (Default) = [TypeLibFlags] 4585 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion]\FLAGS, (Default) = [TypeLibFlags]
4586 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\FLAGS", id, registryVersion), null, flags.ToString(CultureInfo.InvariantCulture.NumberFormat), componentId); 4586 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\FLAGS", id, registryVersion), null, flags.ToString(CultureInfo.InvariantCulture.NumberFormat), componentId);
4587 4587
4588 if (null != helpDirectoryId) 4588 if (null != helpDirectoryId)
4589 { 4589 {
4590 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion]\HELPDIR, (Default) = [HelpDirectory] 4590 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion]\HELPDIR, (Default) = [HelpDirectory]
4591 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\HELPDIR", id, registryVersion), null, String.Concat("[", helpDirectoryId, "]"), componentId); 4591 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\HELPDIR", id, registryVersion), null, String.Concat("[", helpDirectoryId, "]"), componentId);
4592 } 4592 }
4593 } 4593 }
4594 } 4594 }
@@ -4896,10 +4896,10 @@ namespace WixToolset.Core
4896 4896
4897 if (null != command) 4897 if (null != command)
4898 { 4898 {
4899 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat(prefix, "\\shell\\", id), String.Empty, command, componentId); 4899 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat(prefix, "\\shell\\", id), String.Empty, command, componentId);
4900 } 4900 }
4901 4901
4902 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat(prefix, "\\shell\\", id, "\\command"), String.Empty, target, componentId); 4902 this.Core.CreateRegistryStringSymbol(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat(prefix, "\\shell\\", id, "\\command"), String.Empty, target, componentId);
4903 } 4903 }
4904 } 4904 }
4905 4905
diff --git a/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs b/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
index 64ac8651..9046f423 100644
--- a/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
+++ b/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
@@ -155,7 +155,7 @@ namespace WixToolset.Core.ExtensibilityServices
155 return suffix == null ? null : name + suffix; 155 return suffix == null ? null : name + suffix;
156 } 156 }
157 157
158 public Identifier CreateRegistrySymbol(IntermediateSection section, SourceLineNumber sourceLineNumbers, RegistryRootType root, string key, string name, string value, string componentId, bool escapeLeadingHash) 158 public Identifier CreateRegistrySymbol(IntermediateSection section, SourceLineNumber sourceLineNumbers, RegistryRootType root, string key, string name, string value, string componentId, RegistryValueType valueType = RegistryValueType.String, RegistryValueActionType valueAction = RegistryValueActionType.Write)
159 { 159 {
160 if (RegistryRootType.Unknown == root) 160 if (RegistryRootType.Unknown == root)
161 { 161 {
@@ -172,12 +172,6 @@ namespace WixToolset.Core.ExtensibilityServices
172 throw new ArgumentNullException(nameof(componentId)); 172 throw new ArgumentNullException(nameof(componentId));
173 } 173 }
174 174
175 // Escape the leading '#' character for string registry values.
176 if (escapeLeadingHash && null != value && value.StartsWith("#", StringComparison.Ordinal))
177 {
178 value = String.Concat("#", value);
179 }
180
181 var id = this.CreateIdentifier("reg", componentId, ((int)root).ToString(CultureInfo.InvariantCulture.NumberFormat), key.ToLowerInvariant(), (null != name ? name.ToLowerInvariant() : name)); 175 var id = this.CreateIdentifier("reg", componentId, ((int)root).ToString(CultureInfo.InvariantCulture.NumberFormat), key.ToLowerInvariant(), (null != name ? name.ToLowerInvariant() : name));
182 176
183 var symbol = section.AddSymbol(new RegistrySymbol(sourceLineNumbers, id) 177 var symbol = section.AddSymbol(new RegistrySymbol(sourceLineNumbers, id)
@@ -186,12 +180,19 @@ namespace WixToolset.Core.ExtensibilityServices
186 Key = key, 180 Key = key,
187 Name = name, 181 Name = name,
188 Value = value, 182 Value = value,
183 ValueType = valueType,
184 ValueAction = valueAction,
189 ComponentRef = componentId, 185 ComponentRef = componentId,
190 }); 186 });
191 187
192 return symbol.Id; 188 return symbol.Id;
193 } 189 }
194 190
191 public Identifier CreateRegistrySymbol(IntermediateSection section, SourceLineNumber sourceLineNumbers, RegistryRootType root, string key, string name, int value, string componentId)
192 {
193 return this.CreateRegistrySymbol(section, sourceLineNumbers, root, key, name, value.ToString(), componentId, RegistryValueType.Integer);
194 }
195
195 public void CreateSimpleReference(IntermediateSection section, SourceLineNumber sourceLineNumbers, string symbolName, string primaryKey) 196 public void CreateSimpleReference(IntermediateSection section, SourceLineNumber sourceLineNumbers, string symbolName, string primaryKey)
196 { 197 {
197 section.AddSymbol(new WixSimpleReferenceSymbol(sourceLineNumbers) 198 section.AddSymbol(new WixSimpleReferenceSymbol(sourceLineNumbers)