I have a problem when trying to create an XML file from registry. On my laptop(W7 64b) it is working fine, the xml file is generated but on another computer (Xp 32b) an exception is thrown : System.ArgumentException '.', hexadecimal values 0x00, is an invalid character. I have read few useful things about it 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.
I did some experiments:
new XElement("foo\x00bar")
throws on construction.new XAttribute("foo\x00bar", "baz")
throws on construction.new XText("foo\x00bar")
throws only when calling.ToString()
.new XAttribute("foo", "bar\x00baz")
is equivalent tonew XAttribute("foo", new XText("bar\x00baz"))
, so it won't throw on construction.I did not manage to make any of the registry-methods return a string with null-characters, but you should be able to find where this is returned yourself.
You can read more about it here: http://seattlesoftware.wordpress.com/2008/09/11/hexadecimal-value-0-is-an-invalid-character/
And more about it here: XElement & UTF-8 Issue
A valid list of xml chars are here http://en.wikipedia.org/wiki/Valid_characters_in_XML
But essentially you can fix it by removing illegal chars before serialising
Here are a couple little improvements that a) compile, and b) handle surrogate pairs: