c#Registry System.Byte [] to string

时间:2010-01-03 21:07:35

标签: c# string encoding registry

我目前正在编写一个程序,它将读取部分Windows系统注册表,但是这些键的某些值是System.Byte []类型,当我尝试解码这些值时,我可以生成一个具有一定可读性的字符串制作但主要是字符串的字符是jiberish。我尝试了几种编码类型,但似乎都没有产生正确的结果。我只是想知道是否有任何已知的东西可以解决这个问题。这是我的代码

public void getMRU()
{
   String mru = @"Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU";

   RegistryKey rk = Registry.CurrentUser.OpenSubKey(mru);

   foreach (string skName in rk.GetSubKeyNames())
   {
       RegistryKey sk = rk.OpenSubKey(skName);

       System.Text.Encoding enc = System.Text.Encoding.UTF8;
       string myString = enc.GetString((Byte[])sk.GetValue("0"));
       Console.WriteLine(myString)
   }
}

4 个答案:

答案 0 :(得分:4)

正确的解码和解释因密钥而异。对于二进制值,没有强制格式,应用程序可以自由存储他们希望的任何字节。你必须知道你所读到的内容才能解释它。如果记录了关键内容,则可以应用文档规范来解码内容。如果没有记录,那么你没有业务阅读。

答案 1 :(得分:2)

无法保证任何值的注册表中存储的字节必须是编码字符串。如果它们是字符串,那么注册表值的类型就是字符串。

如果它是一个字节值,那么它通常意味着它是对应用程序自定义的某种数据结构的编码,因此您必须弄清楚拥有密钥的应用程序的格式是什么你正在读书。

答案 2 :(得分:2)

从注册表项的名称,我猜这些blob根本不是编码的文件名字符串,而是PIDL(或更确切地说是ITEMIDLISTs)。 PIDL是一个shell结构,表示shell命名空间中的实体,它不必是文件(例如控制面板)。

如果是这种情况,您可能需要使用SHGetPathFromIDList API将PIDL转换为文件系统路径:将 pidl 参数。

答案 3 :(得分:2)

也许这不再是一个问题,但为了帮助其他可能遇到此问题的人,请考虑以下事项:

PIDL或指向项目标识符列表的指针仅存在于Windows NT 6.x(Vista,Win7)中,实际上是从桌面开始而不是C:\ ...(我相信这是由于介绍而完成的“图书馆”)。因此,您需要特殊处理来从PIDL中提取文件路径。

以下方法GetPathFromPIDL()将使用注册表项(byte[]) byteCode并将其转换为特定于平台的IntPtr。然后我们取IntPtr(假设它是一个PIDL)并调用P / Invoke方法SHGetPathFromIDListW(),它将把PIDL的字符串表示放在我们的StringBuilder中。

private string GetPathFromPIDL(byte[] byteCode)
    {
        //MAX_PATH = 260
        StringBuilder builder = new StringBuilder(260);

        IntPtr ptr = IntPtr.Zero;
        GCHandle h0 = GCHandle.Alloc(byteCode, GCHandleType.Pinned);
        try
        {
            ptr = h0.AddrOfPinnedObject();
        }
        finally
        {
            h0.Free();
        }

        SHGetPathFromIDListW(ptr, builder);

        return builder.ToString();
    }

SHGetPathFromIDListW()的原型:

[DllImport("shell32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SHGetPathFromIDListW(IntPtr pidl, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder pszPath);