I need to backup a registry key in C#. I’ve been trying to P/Invoke RegSaveKey to no avail. I can’t use “Reg.exe” to backup the registry due to Group Policy settings which can’t be turned off.
Here’s all of the code:
private static UIntPtr GetKey(string registryPath)
{
UIntPtr hKey = UIntPtr.Zero;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, registryPath, 0, KEY_READ, out hKey) != 0)
{
throw new Exception("Error getting key!");
}
return hKey;
}
private static void ExportRegistry(string registryPath)
{
UIntPtr key = UIntPtr.Zero;
try
{
key = GetKey(registryPath);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return;
}
if (key == UIntPtr.Zero)
{
Console.WriteLine("Not key to export!");
return;
}
try
{
RegSaveKey(key, "c:\\temp\\test.reg", IntPtr.Zero);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
if (key != UIntPtr.Zero)
{
RegCloseKey(key);
}
}
private static int KEY_READ = 131097;
private static UIntPtr HKEY_LOCAL_MACHINE = new UIntPtr(0x80000002u);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int RegCloseKey(UIntPtr hKey);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int RegOpenKeyEx(UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint RegSaveKey(UIntPtr hKey, string lpFile, IntPtr lpSecurityAttributes);
You don’t appear to be checking the return value of either RegOpenKeyEx or RegSaveKey for errors. I suspect that you are getting a return value of ERROR_PRIVILEGE_NOT_HELD. The Registry functions do not use SetLastError they return it directly. And as with virtually every Win32 API call the return value must be checked.
RegSaveKey requires the SE_BACKUP_NAME privilege to be enabled regardless of your ACL access level. So you’ll need to add code to enable this privilege before the call to RegSaveKey and then disable it after the call is complete.
Here’s another question with more info and I’m sure there are others.