c#注册表到XML无效字符问题

c#注册表到XML无效字符问题,c#,xml,registry,invalid-characters,C#,Xml,Registry,Invalid Characters,尝试从注册表创建XML文件时遇到问题。在我的笔记本电脑(W7 64b)上工作正常,生成了xml文件,但在另一台计算机(Xp 32b)上引发了异常:System.ArgumentException“”,十六进制值0x00,是无效字符。我读过一些有用的东西,但我不知道如何解决这种情况,下面是代码: try { string regPath = "SOFTWARE\\IPS"; XElement xRegRoot = new XElem

尝试从注册表创建XML文件时遇到问题。在我的笔记本电脑(W7 64b)上工作正常,生成了xml文件,但在另一台计算机(Xp 32b)上引发了异常:System.ArgumentException“”,十六进制值0x00,是无效字符。我读过一些有用的东西,但我不知道如何解决这种情况,下面是代码:

        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());
        }
    }

提前感谢。

我做了一些实验:

  • new-XElement(“foo\x00bar”)
    用于构建
  • 新的XAttribute(“foo\x00bar”,“baz”)
    用于构造
  • newxtext(“foo\x00bar”)
    仅在调用
    .ToString()
    时抛出
newxattribute(“foo”、“bar\x00baz”)
相当于
newxattribute(“foo”、newxtext(“bar\x00baz”)
,因此它不会影响构造


我没有设法使任何注册表方法返回带有空字符的字符串,但您应该能够自己找到返回的位置。

您可以在此处阅读更多信息:

更多信息请点击此处:

这里有一个有效的xml字符列表

但本质上,您可以通过在序列化之前删除非法字符来修复它

/// <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)
    );
}
//
///从字符串中删除非法的XML字符。
/// 
公共字符串SanitizeXmlString(字符串xml)
{
if(string.IsNullOrEmpty(value))
{
返回值;
}
StringBuilder缓冲区=新的StringBuilder(xml.Length);
foreach(xml中的字符c)
{
if(IsLegalXmlChar(c))
{
缓冲区。附加(c);
}
}
返回buffer.ToString();
}
/// 
///XML 1.0是否允许给定字符。
/// 
公共bool IsLegalXmlChar(int字符)
{
返回
(
字符==0x9/*='\t'==9*/||
字符==0xA/*='\n'==10*/||
字符==0xD/*='\r'==13*/||

(character>=0x20&&character=0xE000&&character=0x10000&&character这里有两个小改进:a)编译,b)处理代理项对:

    /// <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's impossible to get a code point bigger than 0x10FFFF because Char.ConvertToUtf32 would have thrown an exception
        );
    }
//
///从字符串中删除非法的XML字符。
/// 
公共静态字符串SanitizeString(字符串s)
{
if(string.IsNullOrEmpty)
{
返回s;
}
StringBuilder缓冲区=新StringBuilder(s.Length);
对于(int i=0;i(codePoint>=0x20&&codePoint=0xE000&&codePoint=0x10000/*&&character string xmlStringReg=xregoot.ToString();不幸的是,此代码没有清理对非法xml字符的数字引用。例如,࿿;此类数字引用没有通过验证并导致相同的错误。)System.ArgumentException“”,十六进制值0xFFFF,是无效字符