2013-08-25 40 views
8

Tôi đang cố gắng liệt kê một danh sách các giá trị trong Windows registry bằng cách sử dụng Go, nhưng tôi đang gặp một số sự cố. Tôi đã thử hai cách tiếp cận: sử dụng cả thư viện được cung cấp syscall do Go cung cấp để gọi số RegEnumValue, cũng như using a Windows API wrapper by lxn. Trong cả hai trường hợp, tôi gặp vấn đề tương tự. Đây là mã Tôi đang sử dụng (hiện đang được sử dụng thư viện giành chiến thắng từ lxn):Liệt kê các giá trị đăng ký trong 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) 

Trong trường hợp này, RegEnumValue luôn trả về mã 87, mà MSDN's only explanation là "Tham số là không chính xác."

Có ai có bất kỳ ý tưởng nào có thể đưa tôi đi đúng hướng cho điều này không?

Trả lời

5

Một thành viên của phân khu phụ Golang đã chỉ ra rằng tôi đã không thực sự phân bổ bất kỳ bộ nhớ nào cho bộ đệm được chuyển đến RegEnumValue. Do đó, tôi đã sửa ví dụ trên cho các ví dụ sau:

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) 

Rõ ràng, "số ma thuật" 72 có thể được thay thế bằng thứ khác. Có một phương thức khác gọi là RegQueryInfoKey có thể truy xuất thông tin về khoá đăng ký để phân bổ số byte chính xác cho tên và giá trị lớn nhất trong khóa.

+0

Tôi đang cố gắng tìm ra cách để giải mã các lpData đó là trả lại. Bất kỳ gợi ý nào về những gì bạn đang làm với lpData? – freb

1

Có lẽ ai đó tìm thấy này hữu ích:

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

giá trị REG_BINARY sẽ trông giống như "\ x01 \ x00 \ x00 ..."

Các vấn đề liên quan