Open the HKEY_USERS registry root of any Windows user by SID — even when
that user is not logged on.
On Windows, HKEY_USERS\{SID} is only mounted while a user has an active
session. For a user who is not logged on, their NTUSER.DAT hive is not in
memory and must be loaded explicitly. always-hku does this for you and cleans
up afterwards.
Open(sid, access) performs these steps:
- If
HKU\{SID}already exists (user logged on, or hive already mounted), open it directly.Closewill not unload it. - Otherwise read the profile directory from
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\{SID}(theProfileImagePathvalue). - Load
{ProfileDirectory}\NTUSER.DATasHKU\tmp-{SID}. Closeunloads the hive again — but only when this library loaded it.
Loading a hive needs SeBackupPrivilege and SeRestorePrivilege, which a
process normally holds only when running elevated (Administrator or
SYSTEM). Open enables these privileges automatically; if they are not held it
returns an error explaining that the process is likely not elevated.
go get github.com/jc-lab/always-hkupackage main
import (
"fmt"
"log"
alwayshku "github.com/jc-lab/always-hku"
"golang.org/x/sys/windows/registry"
)
func main() {
const sid = "S-1-5-21-1111111111-2222222222-3333333333-1001"
// Pass 0 for access to default to registry.READ.
key, err := alwayshku.Open(sid, registry.READ)
if err != nil {
log.Fatal(err)
}
defer key.Close() // unloads the hive if it was loaded
if key.Loaded() {
fmt.Println("hive was loaded from NTUSER.DAT and will be unloaded on Close")
}
// UserKey embeds registry.Key, so use it like any opened key.
names, err := key.ReadSubKeyNames(-1)
if err != nil {
log.Fatal(err)
}
fmt.Println(names)
}For write access, pass registry.WRITE or registry.ALL_ACCESS (the hive is
loaded read/write in that case).
| Symbol | Description |
|---|---|
Open(sid string, access uint32) (*UserKey, error) |
Open the user's registry root. access == 0 defaults to registry.READ. |
(*UserKey).Close() error |
Close the key; unload the hive if this library loaded it. Idempotent. |
(*UserKey).SID() string |
The SID the key was opened for. |
(*UserKey).Loaded() bool |
Whether this library loaded the hive (so Close will unload it). |
(*UserKey).MountName() string |
The HKEY_USERS subkey name: {SID} or tmp-{SID}. |
UserKey embeds golang.org/x/sys/windows/registry.Key, exposing all of its
methods (GetStringValue, ReadSubKeyNames, SetStringValue, ...).
ErrEmptySID— the SID was blank.ErrProfileNotFound— no profile is registered for the SID underProfileList.ErrUnsupported— returned on non-Windows platforms.
See LICENSE.