2011-04-29 35 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