App is unable to write to the registry, even though the user has administrative privileges

11,933

Solution 1

Just because you're running as Administrator (or using an account with administrative privileges) does not mean that those administrative privileges are always in effect. This is a security measure, preventing malware from exploiting users who foolishly use their computer all the time with administrative privileges.

To wield your administrative privileges, you need to elevate the process. There are two ways to do this:

  1. Use a manifest that indicates your application requires administrative privileges, and thus demand elevation at startup.

    This means your application will always run elevated and should only be used when your application needs this. The Windows Registry Editor (RegEdit), for example, does this, because there's little you can do there without administrative privileges.

    Find information about how to accomplish this here on MSDN, or in my answer here. Basically, you just want to add the following line to your manifest:

    <requestedExecutionLevel level="requireAdministrator" />
    
  2. If you only need administrative privileges for certain tasks (i.e., saving a particular setting to the registry) and the rest of your application does not require it, you should launch a new elevated process to do this. There is no way to temporarily elevate the current process, so you actually need to spin off a new process.

    The advantage of this method is that your application does not have to run with administrative privileges all the time (which increases security), and that users who do not have administrative privileges will still be able to run your app to do everything else (i.e., everything but the one or two tasks that do require elevation).

    You spin off a separate process that contains only the logic needed to write to the registry using the Process class and request elevation for this process using the runas verb. For more information, see this question. I have also written an answer that provides a complete description how to accomplish this from C#, including sample code.

Of course, as other answers have mentioned, it is more likely that the design of your application is incorrect. The whole logic of the Windows security model is that regular applications to not require administrative privileges. They don't need to write to the registry or do other things that could potentially compromise the machine. If you need to persist settings, might I suggest two other possible approaches:

  1. Recognizing that Windows is indeed a multi-user operating system and writing your settings only for the current user. This makes good sense anyway because different users often have different settings and preferences. Instead of the HKEY_LOCAL_MACHINE branch of the registry (which requires administrative privileges to access), you would want to use HKEY_CURRENT_USER. Change your first line of code to:

     RegistryKey softwareKey = Registry.CurrentUser.OpenSubKey("Software", true);
    
  2. Skipping all of the hassle and complication of writing to the registry altogether by using logic built into .NET to persist your application's settings. Start reading the answers here, or here, or on MSDN to learn how to do that. I'd say that this is by far your best option. Don't write complicated code yourself to do something that the framework you use already has built-in support for doing with ease.

Solution 2

The design of your application is probably wrong. Standard desktop apps are not supposed to write to HKEY_LOCAL_MACHINE. Because of UAC, you need to have administrator rights, and be running in an elevated process in order to be able to write to HKLM.

If your application does need to make changes to HKLM then consider doing so at installation time because the installer will be run elevated.

If a desktop application does need to write to HKLM then it should consider separating those parts of the application that need to run elevated into a separate process. Otherwise the users are going to be very fed up with having to go through a UAC dialog in order to run your application. Even if they aren't using the part of the application that writes to HKLM. And if you force the entire app to require elevation then standard users can never run it at all.

Solution 3

The reason you can't create the key under HKEY_LOCAL_MACHINE while running Visual Studio is because Visual Studio isn't running as an elevated process.

For end-users the manifest of the application needs to indicate that full Administrator privileges are required. Here is the documentation on embedding a manifest for UAC

If the registry key doesn't need to be global on the machine consider writing to HKEY_CURRENT_USER instead.

Solution 4

You should to give writable permission adding true value after your key in the method.

Registry.LocalMachine.CreateSubKey(@"YOURKEY", true);
Registry.LocalMachine.OpenSubKey(@"YOURKEY", true);

Also you need elevated permissions to do that, then you can create a .manifest file and setting the level in requireAdministrator like that:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

NOTE: In your code:

RegistryKey softwareKey = Registry.LocalMachine.OpenSubKey("Software", true);
RegistryKey MyKey = softwareKey.CreateSubKey("MyApp");
RegistryKey  = MyKey.CreateSubKey("MyKey");
selfPlacingWindowKey.SetValue("instaldateperson", datestr + usrname);

Check if the object label si correct, you are using the labels softwareKey and MyKey to create an object but to set the value you are using another label selfPlacingWindowKey.

Share:
11,933
user613326
Author by

user613326

By day a designer, programmer, developer, researcher, c++ c# and little bit of electronics. After work a technician, repairman, cook, dishwasher, artist painter, sculptor, scientist. At night i dream in pointers about life the universe and ..

Updated on June 04, 2022

Comments

  • user613326
    user613326 almost 2 years

    I am using Visual Studio 2010, and I'm writing a program that needs to set (and read) new registry values under HKLM\Software\myapp

    The program is .NET 2.0-based and as for now it runs on Windows 7 64-bit. Here is my ocde:

    RegistryKey softwareKey = Registry.LocalMachine.OpenSubKey("Software", true);
    RegistryKey MyKey = softwareKey.CreateSubKey("MyApp");
    RegistryKey  = MyKey.CreateSubKey("MyKey");
    selfPlacingWindowKey.SetValue("instaldateperson", datestr + usrname);     
    

    The problem I have when running Visual Studio 2010, is that it will run the app but logged on as me, I am a user and member of local admin group.. however I cannot create the key (despite I am part of local admin group, who have rights to do so). Neither do I know how to do it as a logon as (but its also not what I want since then I would put Adminuser and password inside the code, and I already am admin ?? so why ??)

    If this isn't possible at all, are there options for creating registry keys?

    Somehow add them to the project or so ??.. I am a bit confused here.