C# 将注册表的键值导出成yaml

本文介绍了如何使用C#编程语言,通过遍历Windows注册表,尤其是HKEY_LOCAL_MACHINE下的键值,实现对注册表的深入理解和数据结构的保存,包括使用YAML格式将注册表内容持久化到文件中。

写在前面

正常C#实现导出注册表的键值可以用 Process类库 呼起 regedit.exe 的方式直接导出.reg 文件;代码如下:

// HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\xxx
private static void ExportReg(string exportPath, string registryPath)
{ 
    string path = "\""+ exportPath + "\"";
    string key = "\""+ registryPath + "\"";
    using (Process proc = new Process())
    {
        try
        {
            proc.StartInfo.FileName = "regedit.exe";
            proc.StartInfo.UseShellExecute = false;
            proc = Process.Start("regedit.exe", "/e " + path + " "+ key);
            proc.WaitForExit();
        }
        catch (Exception ex)
        {
            // 处理异常
            Console.WriteLine(ex.Message);
        }
    }
}

为了测试此前的注册表操作工具类yaml操作工具类,就不用这种方式了,因为后续将需要做注册表的键值快照以便做比对。

通过自行遍历键值的方式也可以更深入的了解注册表的数据存储结构。

代码实现


        private void TestMethod()
        {
            var targetKey = "MongoDB";
            var targetDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "key_files");
            if (!Directory.Exists(targetDir))
            {
                Directory.CreateDirectory(targetDir);
            }

            var controlSet001Key = RegistryHelper.GetRegistryKey(@"SYSTEM\ControlSet001\Services");
            var currentControlSetKey = RegistryHelper.GetRegistryKey(@"SYSTEM\CurrentControlSet\Services");
            if (controlSet001Key != null)
            {
                var subKeyNames = controlSet001Key.GetSubKeyNames();
                if (subKeyNames.Contains(targetKey))
                {
                    // 提取对应的子级键值
                    var targetKeyItem = GetKeyItem(controlSet001Key, targetKey);
                    var filePath = Path.Combine(targetDir, $"{targetKey}.yml");
                    YamlHelper.SerializeToFile(targetKeyItem, filePath);
                }
                controlSet001Key.Close();
            }
            if (currentControlSetKey != null)
            {
                var subKeyNames = currentControlSetKey.GetSubKeyNames();
                if (subKeyNames.Contains(targetKey))
                {
                    // 提取对应的子级键值
                    var targetKeyItem = GetKeyItem(currentControlSetKey, targetKey);
                    var filePath = Path.Combine(targetDir, $"{targetKey}_current.yml");
                    YamlHelper.SerializeToFile(targetKeyItem, filePath);
                }
                currentControlSetKey.Close();
            }
        }
        

        private KeyItem GetKeyItem(RegistryKey parent, string key)
        {
            var subKeyItem = parent.OpenSubKey(key);
            if (subKeyItem == null)
                return null;

            var keyItemConfig = new KeyItem();
            keyItemConfig.Name = key;
 
            var subKeyNames = subKeyItem.GetSubKeyNames();
            if (subKeyNames.Length > 0)
            {
                keyItemConfig.Children = new List<KeyItem>();
                foreach (var subKey in subKeyNames)
                {
                    var subItem = GetKeyItem(subKeyItem, subKey);
                    if (subItem == null) continue;
                    keyItemConfig.Children.Add(subItem);
                }
            }
            if (subKeyItem.ValueCount > 0)
            {
                if (keyItemConfig.Children == null)
                    keyItemConfig.Children = new List<KeyItem>();
                FillSubValues(subKeyItem, keyItemConfig);
            }

            return keyItemConfig;
        }

        private void FillSubValues(RegistryKey registryKey, KeyItem keyItem)
        { 
            var valueNames = registryKey.GetValueNames();
            foreach (var valueName in valueNames)
            {
                var valueItem = new KeyItem();
                valueItem.Name = valueName;
                var value = registryKey.GetValue(valueName);
                if (value != null)
                    valueItem.Value = value.ToString();
                valueItem.Type = (int)registryKey.GetValueKind(valueName);
                keyItem.Children.Add(valueItem);
            }
        }

数据结构: 

        public class KeyItem
        {
            [YamlMember(Alias = "name")]
            public string Name { get; set; }

            [YamlMember(Alias = "value")]
            public string Value { get; set; }

            [YamlMember(Alias = "type")]
            public int Type { get; set; }

            [YamlMember(Alias = "children")]
            public List<KeyItem> Children { get; set; }
        }

操作结果

name: MongoDB
value: 
type: 0
children:
- name: Type
  value: 16
  type: 4
  children: 
- name: Start
  value: 3
  type: 4
  children: 
- name: ErrorControl
  value: 1
  type: 4
  children: 
- name: ImagePath
  value: E:\MongoDb\3.2\bin\mongod.exe --logpath E:\MongoDb\3.2\logs\MongoDB.log --logappend --auth --dbpath E:\MongoDb\3.2\data --directoryperdb --service
  type: 2
  children: 
- name: DisplayName
  value: MongoDB
  type: 1
  children: 
- name: ObjectName
  value: LocalSystem
  type: 1
  children: 
- name: Description
  value: MongoDB Server
  type: 1
  children: 
- name: PreshutdownTimeout
  value: 600000
  type: 4
  children: 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值