Registry: Import & Export in C# (RegSaveKeyEx & RegRestoreKey )

February 10, 2012

one comment

Hi all,

in the last week I found my self messing with the registry, exploring and and learning this repository structure.

As known the ‘REGEDIT application that build-in the Windows O.S. gives the ability to Create / Delete /Update

key and values, but this all also supported in the Framework.

more than that since the framework 4.0 we have more flexibility when working the registry for 64bit machines.

 

But than also the ‘REGEDIT ’ expose the ‘Export’ functionally.

The user can select Key / Value and Export it to a ‘ *.reg ’ file.

This file contains the data that selected and by click it or use CMD ‘REGEDIT.EXE’ the file will import the saved

layout and data (simple override)

Now for that the framework did not supply any functionality,

and like all I believed that the answer is in the Win32, back to native.

 

Than I found the next two functions :

RegSaveKeyEx - Saves the specified key and all of its sub keys and values to a registry file, in the specified format.

RegRestoreKey - Reads the registry information in a specified file and copies it over the specified key. This registry

information may be in the form of a key and multiple levels of sub keys.

 

RegSaveKeyEx:

This function will export the current Key / Sub Key tree to a bin file.  to be able to run this function,

The calling process must have the SE_BACKUP_NAME privilege enabled.

To use this call we should declare it on our project with the next method signature.

   1: [DllImport("advapi32.dll", CharSet = CharSet.Auto)]

   2: public static extern int RegSaveKeyEx(SafeRegistryHandle hKey, string fileName, IntPtr lpSecurityAttributes, int flags);

RegRestoreKey:

This function will import into the current Key / Sub Key tree the data from the bin file. to be able to run this function,

The calling process must have the SE_RESTORE_NAME and SE_BACKUP_NAME privilege enabled.

To use this call we should declare it on our project with the next method signature.

   1: [DllImport("advapi32.dll", CharSet = CharSet.Auto)]

   2: public static extern int RegRestoreKey(SafeRegistryHandle hKey, string fileName, int flags);

privileges:

The save and restore functions are depended on the process privileges, in case that the process missing privileges the action will failed.

The all privileges issue is because that this is actually Backup & Restore actions.

To enable privileges thru the code (C#) we need to run several functions that wrapped in the next function:

   1: private static void SetPrivileges(IEnumerable<string> lookupPrivilegeValues)

   2:         {

   3:             if (lookupPrivilegeValues == null) throw new ArgumentNullException("lookupPrivilegeValues");

   4:             foreach (var item in lookupPrivilegeValues)

   5:             {

   6:                 var hproc = Process.GetCurrentProcess().Handle;

   7:                 var htok = IntPtr.Zero;

   8:                 var retVal = Win32Native.OpenProcessToken(hproc,

   9:                                                           Win32Native.Consts.TokenAdjustPrivileges |

  10:                                                           Win32Native.Consts.TokenQuery, ref htok);

  11:                 if (!retVal) continue;

  12:                 Win32Native.TokPriv1Luid tp;

  13:                 tp.Count = 1;

  14:                 tp.Luid = 0;

  15:                 tp.Attr = Win32Native.Consts.SePrivilegeEnabled;

  16:                 retVal = Win32Native.LookupPrivilegeValue(null, item, ref tp.Luid);

  17:                 if (retVal)

  18:                 {

  19:                     Win32Native.AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);

  20:                 }

  21:             }

  22:         }

Like you can see in the code above we using the next Win32 functions:

  • AdjustTokenPrivileges
  • OpenProcessToken
  • LookupPrivilegeValue

Those are the function signatures

   1: [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]

   2: public static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,

   3: ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);

   4:  

   5: [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]

   6: public static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr

   7: phtok);

   8:  

   9: [DllImport("advapi32.dll", SetLastError = true)]

  10: public static extern bool LookupPrivilegeValue(string host, string name,

  11: ref long pluid);

 

Warp it all:

Lets that it all into the C#, to enable the use more intuitive, other words, make it as an extension method to the ‘ RegistryKey ‘ object

I wrote it like this

   1: public static class RegistryKeyExtensions

   2:     {

   3:         public static void BackupRegKeyToFile(this RegistryKey key, string fileName,

   4:                                               Win32Native.ExportKeyFormat flags =

   5:                                                   Win32Native.ExportKeyFormat.RegStandardFormat,

   6:                                               bool overrideFile = true)

   7:         {

   8:             Helper.BackupRegKeyToFile(key, fileName, flags, overrideFile);

   9:         }

  10:  

  11:         public static void RestoreRegKeyFromFile(this RegistryKey key, string fileName,

  12:                                                  Win32Native.RestoreKeyFormat flags =

  13:                                                      Win32Native.RestoreKeyFormat.RegForceRestore)

  14:         {

  15:             Helper.RestoreRegKeyFromFile(key, fileName, flags);

  16:         }

  17:     }

In that way I have the work flexibility to use an existing RegistryKey with the wanted RegistryView and handler manage from

the framework.

 

Important !

If you will Import the file to the wrong Key, You will override the existing values, if by mistake you will Import it to the

HKLM\Software Key you will KILL  our machine.

So use it carefully

 

To download the code sample, click here

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

one comment

  1. Tony SunApril 1, 2013 ב 03:10

    This is great.
    At the same time, this will not work on Win7 & Win8 with default UAC settings(with default setting).

    The reason is that “AdjustTokenPrivileges” related API invoke will be failed.

    And it works if the user disables the UAC.

    Reply