我试图在整个Windows注册表中监视以查找一些键和值。 有些注册表项无法使用Registry.READ权限打开,因此对于我而言,要读取值和注册表项,我必须使用Registry.QUERY_VALUE和Registry.ENUMERATE_SUB_KEYS权限;
但是,成功使用具有此类许可权的k.OpenKey()(例如HKEY_LOCAL_MACHINE SOFTWARE)打开密钥后,在两种情况下,k.ReadSubKeyNames()函数都会出现错误:

ReadSubKeyNames: HKEY_LOCAL_MACHINE\SOFTWARE Access is denied.

当然,已为管理员启用了实际的注册表项权限QUERY_VALUE和ENUMERATE_SUB_KEYS(我正在使用管理员配置文件)

我应该如何在不使用Registry.READ权限的情况下获得子键名称,这是什么问题?

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
var (
queryVal uint32 = registry.QUERY_VALUE
enumSubs uint32 = registry.ENUMERATE_SUB_KEYS
)      
k, err = registry.OpenKey(globalK, p, queryVal)
    if err != nil {
        logErr(wrapErr(fmt.Sprintf("registry.OpenKey: %s", keyPath), err))
        return
    }
    defer k.Close()


newKey := someLocalType{
}

keyStat, err := k.Stat()
if err != nil {
    logWarn(fmt.Sprintf("Stat: %s %v", keyPath, err))
    return
}
newKey.mod = keyStat.ModTime()

n, err := k.ReadValueNames(-1)
if err != nil {
    logWarn(fmt.Sprintf("ReadValueNames: %s %v", keyPath, err))
    return
}
for _, each := range n {
    v, err := getKeyValue(k, each, keyStat.MaxValueLen)
    if err != nil {
        logWarn(fmt.Sprintf("getKeyValue: %s %v", keyPath, err))
        continue
    }
    newKey.val = append(newKey.val, v)
}

var k1 registry.Key
if len(p) != 0 {
    k1, err = registry.OpenKey(globalK, p, enumSubs)
    if err != nil {
        logErr(wrapErr(fmt.Sprintf("registry.OpenKey: %s", keyPath), err))
        return
    }
    defer k1.Close()
} else {
    k1 = globalK
}

subNames, err := k1.ReadSubKeyNames(-1)
if err != nil {
    logWarn(fmt.Sprintf("ReadSubKeyNames: %s %v", keyPath, err))
    return
}

for _, each := range subNames {
    newPath := joinPath(p, each)
    scanKey(globalK, newPath, c)
}
return

答案是使用组合值:

1
combinedRights := registry.QUERY_VALUE | registry.ENUMERATE_SUB_KEYS

因为k.ReadSubKeyNames()在其中使用k.Stat(),并且k.Stat()要求Registry.QUERY_VALUE权限才能成功返回,然后k.ReadSubKeyNames()使用syscall枚举子项,并且那里是Registry.ENUMERATE_SUB_KEYS 用来。 Windows注册表权限可以在其上使用OR进行汇总,因此就是答案。