7

我正在尝试使用 Go 枚举 Windows 注册表中的值列表,但遇到了一些麻烦。我尝试了两种方法:使用 Go 提供的syscall库调用 into RegEnumValue,以及使用 lxn 的 Windows API 包装器。在这两种情况下,我都有同样的问题。这是我正在使用的代码(目前正在使用来自 lxn 的 win 库):

var root win.HKEY
rootpath, _ := syscall.UTF16PtrFromString("HARDWARE\\DEVICEMAP\\SERIALCOMM")
fmt.Println(win.RegOpenKeyEx(win.HKEY_LOCAL_MACHINE, rootpath, 0, win.KEY_READ, &root))

var name_length uint32 = 72
var name *uint16
var key_type uint32
var lpData *byte
var lpDataLength uint32 = 72
var zero_uint uint32 = 0
fmt.Println(win.RegEnumValue(root, zero_uint, name, &name_length, nil, &key_type, lpData, &lpDataLength))

win.RegCloseKey(root)

在这种情况下,RegEnumValue总是返回代码 87,MSDN 的唯一解释是“参数不正确”。

有没有人有任何想法可以为我指明正确的方向?

4

2 回答 2

5

Golang sub-reddit 的一名成员指出,我实际上并没有为传入的缓冲区分配任何内存RegEnumValue。因此,我已将上述示例更正为以下内容:

var name_length uint32 = 72
var key_type uint32
var lpDataLength uint32 = 72
var zero_uint uint32 = 0
name := make([]uint16, 72)
lpData := make([]byte, 72)

win.RegEnumValue(root, zero_uint, &name[0], &name_length, nil, &key_type, &lpData[0], &lpDataLength)

显然,“幻数” 72 可能应该换成别的东西。还有另一种方法RegQueryInfoKey可以检索有关注册表项的信息,以便为键中的最大名称和值分配正确的字节数。

于 2013-08-25T06:44:17.457 回答
2

也许有人发现这很有用:

const regKey = `SOFTWARE\Microsoft\Windows NT\CurrentVersion`

func getSettingsFromRegistry() (settings map[string]string) {
    settings = make(map[string]string)

    k, err := registry.OpenKey(registry.LOCAL_MACHINE, regKey, registry.QUERY_VALUE)
    if err != nil {
        self.Log.Println("Can't open registry key " + regKey , err)
        return
    }
    defer k.Close()

    params, err := k.ReadValueNames(0)
    if err != nil {
        self.Log.Printf("Can't ReadSubKeyNames %s %#v", psaConfRegistry32, err)
        return
    }

    for _, param := range params {
        val, err := getRegistryValueAsString(k, param)
        if err != nil {
            self.Log.Println(err)
            return
        }
        settings[param] = val
    }

    self.Log.Printf("%#v\n", settings)
    return
}

func getRegistryValueAsString(key registry.Key, subKey string) (string, error) {
    valString, _, err := key.GetStringValue(subKey)
    if err == nil {
        return valString, nil
    }
    valStrings, _, err := key.GetStringsValue(subKey)
    if err == nil {
        return strings.Join(valStrings, "\n"), nil
    }
    valBinary, _, err := key.GetBinaryValue(subKey)
    if err == nil {
        return string(valBinary), nil
    }
    valInteger, _, err := key.GetIntegerValue(subKey)
    if err == nil {
        return strconv.FormatUint(valInteger, 10), nil
    }

    return "", errors.New("Can't get type for sub key " + subKey)
}

REG_BINARY 值看起来像 "\x01\x00\x00..."

于 2016-07-10T18:31:06.750 回答