2010-01-03 66 views
2

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

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

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

2

它不能保证存储在注册表中任何值字节必然编码字符串。如果它们是字符串,那么注册表值的类型就是一个字符串。

如果它是一个字节值,那么它通常意味着它是对应用程序定制的某种数据结构的编码,所以您必须弄清楚拥有该键的应用程序的格式是什么你正在阅读。

2

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

如果是这样的话,你可能需要使用SHGetPathFromIDList API的PIDL转换为文件系统路径:通过在byte []数组作为PIDL参数的地址。

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