1

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()
{
    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

Patrick D'Souza
  • 3,491
  • 2
  • 22
  • 39
E-Max
  • 401
  • 5
  • 14
  • added invoke definition. I didn`t add the ArrayToString, because in debug i can see, that the char[1024] of "\0" is in and char[1024] of "\0" is out. That is why i think, that the problem is in procedure – E-Max Apr 29 '11 at 07:53

2 Answers2

3

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.

Ben Schwehn
  • 4,505
  • 1
  • 27
  • 45
1

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");
}
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • I need to use it because i need to setup WOW64_64Key. – E-Max Apr 29 '11 at 09:09
  • 1
    If you're using .NET 4, you can use the RegistryKey.OpenBaseKey method, see [this answer](http://stackoverflow.com/questions/1074411/how-to-open-a-wow64-registry-key-from-a-64-bit-net-application/2952233#2952233) for details – Thomas Levesque Apr 29 '11 at 10:06