tags:

views:

94

answers:

3

I'm trying to write a simple console app that dumps the contents of HKLM to the console. The output should look something like:

HKEY_LOCAL_MACHINE  
HKEY_LOCAL_MACHINE\BCD00000000
  HKEY_LOCAL_MACHINE\BCD00000000\Description
    KeyName: BCD00000000
    System: 1
    TreatAsSystem: 1
    GuidCache: System.Byte[]
  HKEY_LOCAL_MACHINE\BCD00000000\Objects
    HKEY_LOCAL_MACHINE\BCD00000000\Objects\{0ce4991b-e6b3-4b16-b23c-5e0d9250e5d9}
      HKEY_LOCAL_MACHINE\BCD00000000\Objects\{0ce4991b-e6b3-4b16-b23c-5e0d9250e5d9}\Description
        Type: 537919488
      HKEY_LOCAL_MACHINE\BCD00000000\Objects\{0ce4991b-e6b3-4b16-b23c-5e0d9250e5d9}\Elements
        HKEY_LOCAL_MACHINE\BCD00000000\Objects\{0ce4991b-e6b3-4b16-b23c-5e0d9250e5d9}\Elements\16000020
          Element: System.Byte[]

I haven't had much luck researching how to do this. Any help would be greatly appreciated.

+2  A: 

You know there's already an app that dumps registry contents, right?

REG EXPORT HKLM hklm.reg

Fun part is, it exports the keys in a text format, but that text file can be imported using either REG or the registry editor.

cHao
+2  A: 

cHao way is the safiest approach to your question. In the meanwhile, I was bored on this sunday night and wrote something. Just change the Console.WriteLine or add a few other Console.WriteLine to suit your need, whatever need there is.

class Program
{
    static void Main(string[] args)
    {
        Registry.CurrentUser.GetSubKeyNames()
            .Select(x => Registry.CurrentUser.OpenSubKey(x))
            .Traverse(key =>
            {
                if (key != null)
                {
                    // You will most likely hit some security exception
                    return key.GetSubKeyNames().Select(subKey => key.OpenSubKey(subKey));
                }

                return null;
            })
            .ForEach(key =>
            {
                key.GetValueNames()
                    .ForEach(valueName => Console.WriteLine("{0}\\{1}:{2} ({3})", key, valueName, key.GetValue(valueName), key.GetValueKind(valueName)));
            });

        Console.ReadLine();
    }
}

public static class Extensions
{
    public static IEnumerable<T> Traverse<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> fnRecurse)
    {
        foreach (T item in source)
        {
            yield return item;

            IEnumerable<T> seqRecurse = fnRecurse(item);

            if (seqRecurse != null)
            {
                foreach (T itemRecurse in Traverse(seqRecurse, fnRecurse))
                {
                    yield return itemRecurse;
                }
            }
        }
    }

    public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
    {
        foreach (var item in source)
        {
            action(item);
        }
    }
}
Pierre-Alain Vigeant
thanks alot man, a few minor changes and this solution totally worked for me. ur a lifesaver
Sotelo
A: 

thanks for the answer Pierre-Alain Vigeant, i like ur solution. for the most part it worked with a couple of minor alterations for the text formatting, but i still couldnt deal with the security exception that was being thrown. turns out linq is not so great for this because it does alot of behind the scenes stuff. the following solution is a basic idea of how to do it

class Program
{
    static void Main(string[] args)
    {
        RegistryKey key = Registry.LocalMachine;

        Traverse(key, 0);

        key.Close();
        Console.Read();

    }

    private static void Traverse(RegistryKey key, int indent)
    {
        Console.WriteLine(key.Name);
        string[] names = key.GetSubKeyNames();


        foreach (var subkeyname in names)
        {

            try
            {
                string[] valnames = key.GetValueNames();
                foreach (string valname in valnames)
                {
                    Console.WriteLine(returnIndentions(indent)+valname + ":" + key.GetValue(valname));

                }
                Traverse(key.OpenSubKey(subkeyname),indent++);
            }
            catch { 
            //do nothing
            }
        }
    }

    private static string returnIndentions(int indent)
    {
        string indentions = "";
        for (int i = 0; i < indent; i++) {
            indentions += " ";
        }
        return indentions;
    }

}
Sotelo