"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");
}
精彩评论