我试图使用Go枚举Windows注册表中的值列表,但我遇到了一些麻烦.我尝试了两种方法:使用Go提供的syscall库调用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)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,RegEnumValue始终返回代码87,MSDN的唯一解释是"参数不正确".
有没有人能够指出我正确的方向?
也许有人发现这很有用:
const regKey = `SOFTWARE\Microsoft\Windows NT\CurrentVersion`
func getSettingsFromRegistry() (settings map[string]string, error) {
settings = make(map[string]string)
k, err := registry.OpenKey(registry.LOCAL_MACHINE, regKey, registry.QUERY_VALUE)
if err != nil {
return fmt.Errorf("open registry key %q: %w", regKey, err)
}
defer k.Close()
params, err := k.ReadValueNames(0)
if err != nil {
return fmt.Errorf("read value names %q: %w", psaConfRegistry32, err)
}
for _, param := range params {
val, err := getRegistryValueAsString(k, param)
if err != nil {
return fmt.Errorf("get value as string %q: %w", k, err)
}
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 "", fmt.Errorf("failed to get type for sub key %q", subKey)
}
Run Code Online (Sandbox Code Playgroud)
REG_BINARY 值将类似于“\x01\x00\x00...”
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)
Run Code Online (Sandbox Code Playgroud)
显然,72的"神奇数字"应该被其他东西取代.还有另一种方法RegQueryInfoKey可以检索有关注册表项的信息,以便为密钥中的最大名称和值分配正确的字节数.
| 归档时间: |
|
| 查看次数: |
3035 次 |
| 最近记录: |