2011-04-29 50 views
1

我必须得到注册表分支中的子键列表和值列表。“RegEnumKeyEx”返回空字符串数组(C#调用)

[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]; 
    } 
} 

现在效果很好,但只适用于第一个元素。它返回0-索引的键名,但是对于其他的则返回“”。

这怎么可能?

BTW:我换成你我的定义,做工精良

+0

添加了调用定义。我没有添加ArrayToString,因为在调试中我可以看到,“\ 0”的char [1024]在和“\ 0”的char [1024]不存在。这就是为什么我认为,问题是在程序 – 2011-04-29 07:53:30

回答

3

什么是你的P/Invoke定义RegEnumKeyEx?从pinvoke.net网站,需要一个StringBuilder,而不是一个字符数组的

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

也许,试试这个。这可以排除您不显示的代码中的潜在错误,例如ArrayToString以及您的P/Invoke定义中的错误。

1

你为什么使用P/Invoke?您可以使用Registry类代替...

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

我需要使用它,因为我需要安装WOW64_64Key。 – 2011-04-29 09:09:51

+1

如果您使用.NET 4,则可以使用RegistryKey.OpenBaseKey方法,请参阅[此答案](http://stackoverflow.com/questions/1074411/how-to-open-a-wow64-registry-key -from-a-64-bit-net-application/2952233#2952233)以获得详细信息 – 2011-04-29 10:06:29