Exporting Registry Hives

colins5286

Member
Joined
Nov 8, 2018
Messages
12
Programming Experience
Beginner
I am trying to write a piece of code to export registry keys using C# and the built in reg export command line. This is what I have so far, but it just doesn't work:

C#:
using System;
using System.Diagnostics;
using System.IO;


namespace VolatileDataCapture.Services
{
    class RegistryHiveService
    {
        public void HKEY_Local_Machine()
        {
            try
            {
                string dir = AppDomain.CurrentDomain.BaseDirectory;
                Directory.CreateDirectory(dir + "\\Results\\RegistryHives");
                string outputDirectory = AppDomain.CurrentDomain.BaseDirectory + "Results\\RegistryHives\\";
                Process regexportProcess = new Process();
                regexportProcess.StartInfo.FileName = "reg export";
                regexportProcess.StartInfo.UseShellExecute = false;
                regexportProcess.StartInfo.Arguments = "HKEY_LOCAL_MACHINE " + outputDirectory + "HKEY_LOCAL_MACHINE.reg";
                regexportProcess.Start();
                regexportProcess.WaitForExit();
            }
            catch { }
        }
    }
}
 
You probably need to run as elevated administrator. Try run Visual Studio as admin and then start the application debug.
 
Also, instead of just eating the exceptions, catch them and look at the messages. They may inform you as to what maybe failing.
 
Hmm, maybe the other two seem to think its alright to be messing around in the windows registry, but I don't. And unless you have a good reason for being in there, you really shouldn't, especially if you don't know what you're doing. Why are you importing/exporting registry settings through code? Just curious.

If your StartInfo.Arguments are anything to go by, I'd recommend you do some research into StartInfo.Arguments because you should be passing in the regedit.exe first, and so on with your arguments. You should also use StartInfo.Verb="runas" for elevated permissions. Or to avoid that, you could try use reg.exe but I'm not sure if that still exists in Windows 7 and the later, as I haven't tried it, but you can.

What you need to do is send the file as a parameter to regedit.exe. Or reg.exe which might still work and likely won't require you to elevate permissions. Step into your debugger to check what your arguments are outputting; as they may not be what you're expecting. Does this look like you are following standard principles when forming a registry path? I think not.
Screenshot_20.jpg

Check out the try catch link in my signature, as its not good practice to accept errors blindly and allow them to roll off like that without scrutiny and handling. That's actually really crappy programming. Generally people catch the error with the specific exceptions there code are known to throw and handle the exception accordingly to a specific error. And not with the baseline exception : exception ex as I am demonstrating as this will catch all errors and not specific errors, and its really better to be explicit in these situations.

With that said, assuming you wish to export registry before you add registry values from your own application, you should first consider storing whatever values you have to an xml or a settings file such as a ini file, rather than using the registry itself. If you prefer to disregard my suggestion, you need to clarify clearly what you're trying to backup/import/export.
 
Yes, in general messing with the registry is something that should be approached with a lot of caution.

I wasn't too worried though, when I saw the namespace for the code was "VolatileDataCapture.Services" and that he was only doing an export operation. I'm guessing the OP is trying to put together a poor man's pre and post installation comparison tool to see what changed on a particular machine. I know of some teams tasked with testing 3rd party software for installation on systems, and one of the things they need to test is whether the 3rd party software uninstalls cleanly -- no leftover turds in the filesystem or registry.
 
Well I guessed as much too, but you do need to ask these things. ;) Here is a simple blunt but working version :
You can call the below code which will export the registry of the registryLocation path. Call with :
Calling code:
ExportRegistry(exportTo, registryLocation, "exported.reg")
Upon compile, these variables will be set readonly : readonly string exportTo = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); AND readonly string registryLocation = @"HKEY_CURRENT_USER\Software\7-Zip"; exportTo will set the path you will save too; to be your desktop folder. While registryLocation will be the registry you wish to export.
We pass these into the method private static void ExportRegistry(string exportPath, string registryPath, string exportFileName) with the calling code ExportRegistry(exportTo, registryLocation, "exported.reg"). Note, the last parameter is passing in the file name of the file we will be exporting.

You can see I combine the path with the filename Path.Combine(exportPath, exportFileName) inside the Process.Start method, where it then becomes one path. You will also notice I dropped the
StartInfo.Arguments from your code and simply ran the parameters inside the Process.Start method, and this will suffice as the regedit would similarly take command arguments in the same way if you were doing this with the cmd command line. Tested and working :

6jEOtea.gif


Source:
        readonly string exportTo = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        readonly string registryLocation = @"HKEY_CURRENT_USER\Software\7-Zip";
        private static void ExportRegistry(string exportPath, string registryPath, string exportFileName)
        {
            Process regProcess = new Process();
            try
            {
                regProcess.StartInfo.FileName = "regedit.exe";
                regProcess.StartInfo.UseShellExecute = false;
                regProcess = Process.Start("regedit.exe", "/e " + Path.Combine(exportPath, exportFileName) + " " + registryPath + "");
                regProcess.WaitForExit();
            }
            catch (ArgumentNullException ane)
            {
                /* Handle error here */
            }
            catch (InvalidOperationException ioe)
            {
                /* Handle error here */
            }
            catch (Exception ex)
            {
                /* Handle all other errors here */
                regProcess.Dispose();
            }
            if (regProcess.HasExited ? true : false)
            regProcess.Dispose();
        }

One more thing, if you are looking for the correct registry value path, you can simply run regedit, and then navigate the tree on the left and when you find what you want to export in code, you can right click and export, and in the box below it will show you the path to those keys path. Simply copy that and replace the value in registryLocation. Gif for example purpose :

X6hsDPl.gif


Hope it helps.
 
Last edited:
Thanks everyone for your help on this one.
I did some debugging and found that I had messed up on the parameters. I needed to move the 'export' switch to the .Arguments line. It works a treat now.
I do take care of the error handling too - that is dealt with when I refine the code. I just needed to get it working first.

C#:
using System;
using System.Diagnostics;
using System.IO;


namespace VolatileDataCapture.Services
{
    class RegistryHiveService
    {
        public void ExtractHKLMHive()
        {
            try
            {
                string dir = AppDomain.CurrentDomain.BaseDirectory;
                Directory.CreateDirectory(dir + "\\Results\\RegistryHives");
                string outputDirectory = AppDomain.CurrentDomain.BaseDirectory + "Results\\RegistryHives\\";
                Process regexportProcess = new Process();
                regexportProcess.StartInfo.FileName = "reg";
                regexportProcess.StartInfo.UseShellExecute = false;
                regexportProcess.StartInfo.Arguments = "export HKEY_LOCAL_MACHINE " + outputDirectory + "HKEY_LOCAL_MACHINE.reg";
                regexportProcess.Start();
                regexportProcess.WaitForExit();
            }
            catch { }
        }
    }
}
 
Remember when passing parameters here StartInfo.Arguments and here Process.Start("regedit.exe", "/e " + Path.Combine(exportPath, exportFileName) + " " + registryPath + ""); to write it as you would if you're writing a desktop shortcut or writing it in cmd.

Glad that example helped you understand your mistake, and if you are in doubt regarding how something works, always look it up on MSDN for some example code to help you understand where you go wrong.

One more thing, consider using using blocks on your Process definition, or dispose of it when its completed its task, which you currently are not.
 
Last edited:
Back
Top Bottom