Перечисление значений реестра в Go (Golang)
Я пытаюсь перечислить список значений в реестре Windows с помощью Go, но у меня возникли проблемы. Я пробовал два подхода: используя оба Go-provided syscall
библиотека для вызова RegEnumValue
, а также использование оболочки Windows API lxn. В обоих случаях у меня одна и та же проблема. Это код, который я использую (который в настоящее время использует библиотеку win из lxn):
var root win.HKEY
rootpath, _ := syscall.UTF16PtrFromString("HARDWAREDEVICEMAPSERIALCOMM")
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 is " параметр неверен."
есть ли у кого-нибудь идеи, которые могут указать мне в правильном направлении для этого?
2 ответов
член 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
это может получить информацию о разделе реестра, чтобы выделить правильное количество байтов для наибольшего имени и значения в ключе.
может быть, кто-то нашел это полезным:
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\х00\х00..."