3

We are trying to add a key value pair into the Windows registry using C#.

The key to write is an Environment variable for another user. The user will be a Service User, and never log on.

We have been able to get the user SID, and add it to the Registry, by P/Invoking LoadUserProfile.

However, when trying to write to the Environment Sub Key there is a problem:

        using (var key = Registry.Users.OpenSubKey(userSid + "\\Environment"))
        {
            if (key == null)
            {
                Debug.WriteLine("Key was null (typical)");
                return;
            }

            key.SetValue("A", "B");
        }

This throws an UnauthorizedAccessException with the really helpful message

Cannot write to the registry key

The application is running as an administrator.

For obvious reasons I am guessing it is something to do with the security access control. I can get the access control, using var security = key.GetAccessControl(); However, I don't know what values to change to be able to write to the Environment.

Just for the record, I can write values to some other keys such as HKEY_USERS itself, or HKEY_LOCAL_MACHINE itself, but I cannot write to HKEY_LOCAL_MACHINE\Public for example.

Here is the stack trace if it helps:

************** Exception Text **************
System.UnauthorizedAccessException: Cannot write to the registry key.
   at System.ThrowHelper.ThrowUnauthorizedAccessException(ExceptionResource resource)
   at Microsoft.Win32.RegistryKey.EnsureWriteable()
   at Microsoft.Win32.RegistryKey.SetValue(String name, Object value, RegistryValueKind valueKind)
   at Microsoft.Win32.RegistryKey.SetValue(String name, Object value)
   at TestingEnvVariables.Form1.GetVariablesButtonClick(Object sender, EventArgs e)
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
David Setty
  • 609
  • 1
  • 6
  • 16

1 Answers1

4

Bingo!

From the MSDN article on RegistryKey.OpenSubKey(String):

Retrieves a subkey as read-only.

You need RegistryKey.OpenSubKey(String, Boolean) (MSDN article):

Retrieves a specified subkey, and specifies whether write access is to be applied to the key.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158