C # Registry for XML Invalid character problem

I had a problem trying to create an XML file from the registry. It works fine on my laptop (W7 64b), an xml file is generated, but an exception is thrown on another computer (Xp 32b): System.ArgumentException '.', Hexadecimal values ​​0x00, is an invalid character. I read some useful things about this, but I don’t know how to solve in this case, here is the code:

try { string regPath = "SOFTWARE\\IPS"; XElement xRegRoot = new XElement("Root", new XAttribute("Registry", regPath)); ReadRegistry(regPath, xRegRoot); string xmlStringReg = xRegRoot.ToString(); XmlDocument docR = new XmlDocument(); docR.LoadXml(xmlStringReg); docR.Save(AppDomain.CurrentDomain.BaseDirectory + "\\_RegistryList.xml"); } catch (System.Exception ex) { Console.WriteLine(ex.ToString()); LogToFile(ex.ToString()); } private static void ReadRegistry(string keyPath, XElement xRegRoot) { string[] subKeys=null; RegistryKey HKLM = Registry.LocalMachine; RegistryKey RegKey = HKLM.OpenSubKey(keyPath); try { subKeys = RegKey.GetSubKeyNames(); foreach (string subKey in subKeys) { string fullPath = keyPath + "\\" + subKey; Console.WriteLine("\r\nKey Name | " + fullPath); LogToFile("Key Name | " + fullPath); XElement xregkey = new XElement("RegKeyName", new XAttribute("FullName", fullPath), new XAttribute("Name", subKey)); xRegRoot.Add(xregkey); ReadRegistry(fullPath, xRegRoot); } string[] subVals = RegKey.GetValueNames(); foreach (string val in subVals) { string keyName = val; string keyType = RegKey.GetValueKind(val).ToString(); string keyValue = RegKey.GetValue(val).ToString(); Console.WriteLine("Key Value | " + keyType + " | " + keyName + " | " + keyValue); LogToFile("Key " + keyType + " | " + keyName + " | " + keyValue); XElement xregvalue = new XElement("RegKeyValue", new XAttribute("keyType", keyType), new XAttribute("keyName", keyName), new XAttribute("keyValue", keyValue)); xRegRoot.Add(xregvalue); } } catch (System.Exception ex) { Console.WriteLine(ex.ToString()); LogToFile(ex.ToString()); } } 

Thanks in advance.

+2
c # xml registry
source share
4 answers

Here are a few small enhancements that: a) compile and b) process surrogate pairs:

  /// <summary> /// Remove illegal XML characters from a string. /// </summary> public static string SanitizeString(string s) { if (string.IsNullOrEmpty(s)) { return s; } StringBuilder buffer = new StringBuilder(s.Length); for (int i = 0; i < s.Length; i++) { int code; try { code = Char.ConvertToUtf32(s, i); } catch (ArgumentException) { continue; } if (IsLegalXmlChar(code)) buffer.Append(Char.ConvertFromUtf32(code)); if (Char.IsSurrogatePair(s, i)) i++; } return buffer.ToString(); } /// <summary> /// Whether a given character is allowed by XML 1.0. /// </summary> private static bool IsLegalXmlChar(int codePoint) { return (codePoint == 0x9 || codePoint == 0xA || codePoint == 0xD || (codePoint >= 0x20 && codePoint <= 0xD7FF) || (codePoint >= 0xE000 && codePoint <= 0xFFFD) || (codePoint >= 0x10000/* && character <= 0x10FFFF*/) //it impossible to get a code point bigger than 0x10FFFF because Char.ConvertToUtf32 would have thrown an exception ); } 
+2
source share

I did some experiments:

  • new XElement("foo\x00bar") fires when built.
  • new XAttribute("foo\x00bar", "baz") fires when built.
  • new XText("foo\x00bar") is called only when new XText("foo\x00bar") is called.

new XAttribute("foo", "bar\x00baz") equivalent to new XAttribute("foo", new XText("bar\x00baz")) , so it will not build the construct.

I was not able to get any of the registry methods to return a string with null characters, but you should find where this is returned.

+4
source share

You can read more about this here: http://seattlesoftware.wordpress.com/2008/09/11/hexadecimal-value-0-is-an-invalid-character/

And more about that here: XElement and UTF-8 Issue

A valid list of xml characters is here http://en.wikipedia.org/wiki/Valid_characters_in_XML

But essentially you can fix this by deleting illegal characters before serializing

 /// <summary> /// Remove illegal XML characters from a string. /// </summary> public string SanitizeXmlString(string xml) { if (string.IsNullOrEmpty(value)) { return value; } StringBuilder buffer = new StringBuilder(xml.Length); foreach (char c in xml) { if (IsLegalXmlChar(c)) { buffer.Append(c); } } return buffer.ToString(); } /// <summary> /// Whether a given character is allowed by XML 1.0. /// </summary> public bool IsLegalXmlChar(int character) { return ( character == 0x9 /* == '\t' == 9 */ || character == 0xA /* == '\n' == 10 */ || character == 0xD /* == '\r' == 13 */ || (character >= 0x20 && character <= 0xD7FF ) || (character >= 0xE000 && character <= 0xFFFD ) || (character >= 0x10000 && character <= 0x10FFFF) ); } 
+3
source share

I have been looking for a similar opportunity for several days. To export an entire registry branch to XML and import it again. It also should not be XML. Only for saving and restoring registry entries without using the resources of the Windows board they are blocked by group policies.

Can I get the full code?

0
source share

All Articles