【问题标题】:"RegEnumKeyEx" returns array of empty strings (C# invoke)"RegEnumKeyEx" 返回空字符串数组(C# 调用)
【发布时间】:2011-04-29 07:32:25
【问题描述】:

我必须在注册表分支中获取子键列表和值列表。

[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-index 的键名,但对于其他它返回 ""。

怎么可能?

顺便说一句:我把我的定义换成了你的,很好用

【问题讨论】:

  • 添加了调用定义。我没有添加 ArrayToString,因为在调试中我可以看到,“\0”的 char[1024] 已输入,而“\0”的 char[1024] 已输出。这就是为什么我认为问题出在程序中

标签: c# registry


【解决方案1】:

RegEnumKeyEx 的 P/Invoke 定义是什么?

也许,试试这个:

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

来自pinvoke.net 站点,该站点采用字符串构建器而不是字符数组。这将排除您未显示的代码中的潜在错误,例如 ArrayToString 和您的 P/Invoke 定义中,您也没有显示。

【讨论】:

    【解决方案2】:

    您为什么要为此使用 P/Invoke?您可以改用Registry 类...

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

    【讨论】:

    • 我需要使用它,因为我需要设置WOW64_64Key。
    • 如果你使用.NET 4,你可以使用RegistryKey.OpenBaseKey方法,详情见this answer
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    相关资源
    最近更新 更多