开发者

"RegEnumKeyEx" returns array of empty strings (C# invoke)

I have to get a list of the subkeys and a list of values in Registry branch.

[DllImport("advapi32.dll", EntryPoint="RegEnumKeyExW",
            CallingConvention=CallingConvention.Winapi)]
[MethodImpl(MethodImplOptions.PreserveSig)]
extern private static int RegEnumKeyEx(IntPtr hkey, uint index,
                        char[] lpName, ref uint lpcbName,
                            IntPtr reserved, IntPtr lpClass, IntPtr lpcbClass,
                        out long lpftLastWriteTime);


// Get the names of all subkeys underneath this registry key.
public String[] GetSubKeyNames()
开发者_JS百科{
    lock(this)
    {
        if(hKey != IntPtr.Zero)
        {
            // Get the number of subkey names under the key.
            uint numSubKeys, numValues;
            RegQueryInfoKey(hKey, null,IntPtr.Zero, IntPtr.Zero,out numSubKeys, IntPtr.Zero, IntPtr.Zero, out numValues,IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);

            // Create an array to hold the names.
            String[] names = new String [numSubKeys];
            StringBuilder sb = new StringBuilder();
            uint MAX_REG_KEY_SIZE = 1024;
            uint index = 0;
            long writeTime;
            while (index < numSubKeys)
            {
                sb = new StringBuilder();
                if (RegEnumKeyEx(hKey,index,sb,ref MAX_REG_KEY_SIZE, IntPtr.Zero,IntPtr.Zero,IntPtr.Zero,out writeTime) != 0)
                {
                    break;
                }
                names[(int)(index++)] = sb.ToString();
            }
            // Return the final name array to the caller.
            return names;
        }
        return new String [0];
    }
}

It now works well, but only for the first element. It returns keyname for the 0-index, but for other it returns "".

How can it be?

BTW: I replaced my definition by yours, work well


What is your P/Invoke definition for RegEnumKeyEx?

Perhaps, try this one:

[DllImport("advapi32.dll", EntryPoint = "RegEnumKeyEx")]
extern private static int RegEnumKeyEx(UIntPtr hkey,
    uint index,
    StringBuilder lpName,
    ref uint lpcbName,
    IntPtr reserved,
    IntPtr lpClass,
    IntPtr lpcbClass,
    out long lpftLastWriteTime);

from the pinvoke.net site that takes a stringbuilder instead of a character array. This would rule out potential errors in the code you don't show such as ArrayToString and in your P/Invoke definition, that you also don't show.


Why are you using P/Invoke for this? You can use the Registry class instead...

using (RegistryKey key = Registry.LocalMachine.OpenSubKey("SomeKey"))
{
    string[] subKeys = key.GetSubKeyNames();
    string[] valueNames = key.GetValueNames();
    string myValue = (string)key.GetValue("myValue");
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜