c# Registry System.Byte[] to string

让人想犯罪 __ 提交于 2020-08-25 08:02:51

问题


I am currently writing a program that will read part of the windows system registry however some of the values of these keys are of type System.Byte[] when i try and decode these values I can produce a string that has some readable characters that makes but mostly the string is jiberish. I have tried several encoding types but none seem to produce the correct results. I am just wondering if there is anything that is known to fix this. this is the code i have

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

回答1:


The correct decoding and interpretation varies from key to key. For binary values there is no enforced format, applications are free to store any bytes they wish. You must know what you read in order to interpret it. If the key content is documented, then you can apply the documentation specifications to decode the content. If is undocumented, then you have no business reading it.




回答2:


Perhaps this is no longer an issue, but to help anyone else who might encounter this problem consider the following:

A PIDL, or pointer to an item identifier list only exists in Windows NT 6.x (Vista, Win7) and actually starts at the desktop rather than C:\... (I believe this was done due to the introduction of "libraries"). Thus, you need special handling to extract a file path from a PIDL.

The following method, GetPathFromPIDL(), will take a registry key's (byte[]) byteCode and covert it to a platform specific IntPtr. Then we take the IntPtr (given that it is a PIDL) and call the P/Invoke method SHGetPathFromIDListW(), which will put the string representation of the PIDL in our 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();
    }

Prototype for SHGetPathFromIDListW():

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



回答3:


It's not guaranteed that the bytes that are stored in the registry for any value are necessarily encoded strings. If they were to be strings, then the type of the registry value would be just that, a string.

If it is a byte value, then it usually means that it is an encoding of some sort of data structure that is custom to the application, so you have to figure out what the format is for the application which owns the key that you are reading.




回答4:


From the name of the registry key, I would guess that those blobs aren't encoded filename strings at all, but instead are PIDLs (or rather ITEMIDLISTs). A PIDL is a shell structure representing an entity in the shell namespace, which need not be a file (e.g. Control Panel).

If that's the case, you'll probably need to use the SHGetPathFromIDList API to convert the PIDL to a filesystem path: pass in the address of the byte[] array as the pidl parameter.



来源:https://stackoverflow.com/questions/1996318/c-sharp-registry-system-byte-to-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!