2013-08-25 7 views
8

Sto tentando di enumerare un elenco di valori nel registro di Windows utilizzando Go, ma sto riscontrando dei problemi. Ho provato due approcci: utilizzare la libreria syscall fornita da Go per chiamare RegEnumValue e using a Windows API wrapper by lxn. In entrambi i casi, sto avendo lo stesso problema. Questo è il codice che sto usando (che sta attualmente utilizzando la libreria vittoria da LXn):Enumerazione dei valori di registro in Go (Golang)

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) 

In questo caso, RegEnumValue restituisce sempre il codice 87, che MSDN's only explanation è "Il parametro non è corretto."

Qualcuno ha qualche idea che possa indicarmi la giusta direzione per questo?

risposta

5

Un membro del sotto-reddit di Golang ha sottolineato che in realtà non stavo allocando alcuna memoria ai buffer passati a RegEnumValue. Come tale, ho corretto l'esempio precedente al seguente:

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) 

Ovviamente, il "numero magico" di 72 dovrebbe probabilmente essere sostituito con qualcos'altro. Esiste un altro metodo chiamato RegQueryInfoKey che può recuperare informazioni sulla chiave del Registro di sistema per allocare il numero corretto di byte per il nome e il valore più grande nella chiave.

+0

Sto cercando di capire come decodificare il lpData che è restituito. Qualche suggerimento su cosa stai facendo con lpData? – freb

1

Forse qualcuno pensa che questa utile:

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) 
} 

valori REG_BINARY volontà osserva come "\ x01 \ x00 \ x00 ..."

Problemi correlati