11

I tried to write a registry subkey and its corresponding value to registry like this:

const string subKey = @"SOFTWARE\Apple\Banana\";
const string regKey = "pip";

var rk = Registry.LocalMachine.OpenSubKey(subKey);
if (rk == null)
    rk = Registry.LocalMachine.CreateSubKey(subKey);

var rv = rk.GetValue(regKey);
if (rv == null)
    rk.SetValue(regKey, "XXX");

return rv.ToString();

Now the problem is that I when I look in the location manually (via regedit) I cannot see the folder SOFTWARE\Apple\Banana in HKLM.

But when I run the above code again and debug, I can see that both Registry.LocalMachine.OpenSubKey(subKey) and rk.GetValue(regKey) yields the before saved values. Yet I do not see the values in the given location via regedit. So on searching the registry, I can see the above keys and values in following locations:

  1. HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE\Apple\Banana

  2. HKEY_USERS\S-1-5-21-44266131-1313801407-2392705078-1000\Software\Classes\VirtualStore\MACHINE\SOFTWARE\Apple\Banana

Under both which the values remain exactly as I saved. So I realise this is from where my app reads the value though in my code I call it from HKLM\SOFTWARE\Apple\Banana\..

  1. Why is this happening? Is it related to access rights issue?

  2. Is this expected behaviour? In the sense, this value is very important to me, so I am just knowing if there is some risk associated with auto-relocation!

  3. Is there a proper way of writing to registry so that it remains in its exact location..

My account is administrator one, and I am using 32 bit windows 7.

Edit: As I came to know, the registry entry is stored in current users location rather than HKLM. And when I query for the reg value from a different account, I do not get the value. In short, no point in first of all saving it to HKLM :(

M.M
  • 138,810
  • 21
  • 208
  • 365
nawfal
  • 70,104
  • 56
  • 326
  • 368
  • Reply to your comment "but doesn't this mean a future user querying the same location in hklm wont get the value which resides in current users location? Ok I am going to test it anyway" - yes it does. HLM in registry and Program Files and ProgramData directories should only be written to during setup. Only administrators can write there otherwise (and only with elevation if UAC is enabled). – Danny Varod Jun 08 '12 at 00:13
  • @DannyVarod I did not get your first sentence. Anyway when I tested I came to learn that virtualization doesnt help if you want to get the same registry value for all users.. – nawfal Jun 08 '12 at 00:20
  • There are various locations in Windows 6+ that are meant to hold setup data only and there are other locations that are meant to hold configurable data or data that changes during run time. During setup, users are granted permission to write to the setup locations (by admin via UAC). During runtime windows prevents access to these locations unless user is admin. (Non admins shouldn't affect other users.) – Danny Varod Jun 08 '12 at 01:29

2 Answers2

6

Yes this is correct behaviour and it is happening because you have insufficient privileges to write directly to the HKLM hive. It's called virtualisation and happens for the file system as well, it has been a behaviour in the OS since Vista.

You should continue as you are and attempt to also read from the same HKLM key you are writing to, Windows will transparently redirect for you.

Preet has kindly provided a MSDN link which you should read thoroughly.

Note that when you access a key under HKLM you should also include the permissions you want, even if you are running as administrator (because the key is not automatically opened with admin rights, you have to request it):

key = key.OpenSubKey(keyname, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl);
Community
  • 1
  • 1
slugster
  • 49,403
  • 14
  • 95
  • 145
  • but doesn't this mean a future user querying the same location in hklm wont get the value which resides in current users location? Ok I am going to test it anyway.. – nawfal Jun 07 '12 at 23:53
  • I'm having the same problem, but I'm trying to save an activation key to the registry. I want the key to be the same for all users, will this virtualization mess that up? – Alan Feb 07 '13 at 22:04
  • @Alan Yes it will - but if you are trying to write a key for all users then you need to specify (demand) the appropriate rights when you open the key (which will result in a UAC prompt being shown if necessary). – slugster Feb 07 '13 at 22:23
  • 1
    @slugster Can I read an HKLM key without elevating? I was considering saying.. oh well who cares.. they can type in the key per user (same key) once in their life (virtualized), but if they run the program as admin initially during activation (I'm assuming it isn't virtualized), would a subsequent non-admin run fail to read the key? – Alan Feb 07 '13 at 22:32
  • @Alan I haven't tried it lately, but IIRC you should be able to read from HKLM no problem (although I've had times where I've still had to explicitly mention the read rights I want, it would fail if I didn't). Usually it will be the write that is virtualised, and subsequent reads from the same location will read the virtualised value. – slugster Feb 08 '13 at 01:42
5
  1. This is Registry Virtualization (msdn)

    Registry virtualization is an application compatibility technology that enables registry write operations that have global impact to be redirected to per-user locations. This redirection is transparent to applications reading from or writing to the registry. It is supported starting with Windows Vista.

    Virtualization Overview

    Prior to Windows Vista, applications were typically run by administrators. As a result, applications could freely access system files and registry keys. If these applications were run by a standard user, they would fail due to insufficient access rights. Windows Vista and later versions of Windows improve application compatibility for these applications by automatically redirecting these operations. For example, registry operations to the global store (HKEY_LOCAL_MACHINE\Software) are redirected to a per-user location within the user's profile known as the virtual store (HKEY_USERS\_Classes\VirtualStore\Machine\Software).

  2. Yes it is exactly as it should be.

  3. Either live with Virtualization if you want to write to globally impacting location, or use more localised locations if you don't want it. Either way it's invisible to the reader, so don't worry about it.

Preet Sangha
  • 64,563
  • 18
  • 145
  • 216
  • 1
    @slugster - I think it's important to put links to quoted text or other peoples samples/blogs. – Preet Sangha Jun 07 '12 at 23:50
  • but doesn't this mean a future user querying the same location in hklm wont get the value which resides in current users location? Ok I am going to test it anyway.. – nawfal Jun 07 '12 at 23:52
  • I'm having the same problem, but I'm trying to save an activation key to the registry. I want the key to be the same for all users, will this virtualization mess that up? – Alan Feb 07 '13 at 22:04
  • @Alan - See http://stackoverflow.com/questions/5409381/how-to-set-reg-key-dont-virtualize-flag-in-c-sharp – Preet Sangha Feb 07 '13 at 23:19