خواندن/نوشتن رجیستری ویندوز با کد #C

دوشنبه 24 اسفند 1394

در این مقاله می خواهیم یک کلاس پایه ایجاد کنیم که هدف اصلی آن نوشتن/خواندن داده در/از رجیستری ویندوز باشد. سپس می توانیم از این کلاس استفاده های بیشتری طبق منطق اپلیکیشن خود داشته باشیم.

خواندن/نوشتن رجیستری ویندوز با کد #C

کلاس های اصلی که شما به آنها نیاز دارید در mscorlib.dll و در فضای نام Microsoft.Win32  قرار دارد. این DLL به طور پیش فرض از پروژه های NET. رفرنس داده شده است بنابراین شما فقط باید یک using برای این namespace اضافه کنید.

خواندن/نوشتن رجیستری ویندوز با استفاده از #C

در ادامه می توانید ساختار پیش فرض رجیستری در ویندوز را ببینید. درخت پوشه ها (کلید های فرعی) شامل کلیدهایی با Name، نوع(Type) و مقدار(Value) می باشد. برای اینکه بتوانید با آنها کار کنید ابتدا باید آنها را باز کنید. زمانی که شما این را انجام می دهید می توانید عملگرهای خواندن/نوشتن را انجام دهید:

RegistryKey key;
key = Registry.CurrentUser.CreateSubKey("Names");
key.SetValue("Name", "Isabella");
key.Close();

کد بالا یک فولدر با نام HKEY_CURRENT_USER ایجاد کرده و یک کلید با نام Name ایجاد می کند که مقدار آن Isabella و از نوع رشته می باشد.

برای عملیات خواندن، می توانید از متدهای OpenSubKey و GetValue استفاده کنید.

تا اینجا همه چیز خوب است. اما حتما شما نمی خواهید این 3-4 خط کد را برای هر عملیات خواندن/نوشتن بنویسید. بلکه می توانید از کد زیر برای یک کلاس سرویس قابل استفاده مجدد استفاده کنید:

using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.Win32;

    public abstract class BaseRegistryService
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        protected string MainRegistrySubKey;

        protected void Write(string subKeys, Object value)
        {
            string[] subKeyNames = subKeys.Split('/');
            List<RegistryKey> registryKeys = new List<RegistryKey>();
            for (int i = 0; i < subKeyNames.Length; i++)
            {
                RegistryKey currentRegistryKey = default(RegistryKey);
                if (i == 0)
                {
                    currentRegistryKey = Registry.CurrentUser.CreateSubKey(subKeyNames[i]);
                }
                else if (i < subKeyNames.Length - 1)
                {
                    currentRegistryKey = registryKeys[i - 1].CreateSubKey(subKeyNames[i]);
                }
                else
                {
                    registryKeys.Last().SetValue(subKeyNames.Last(), value);
                }
                registryKeys.Add(currentRegistryKey);
            }

            this.CloseAllRegistryKeys(registryKeys);
        }

        protected Object Read(string subKeys)
        {
            Object result = default(Object);

            try
            {
                string[] subKeyNames = subKeys.Split('/');
                List<RegistryKey> registryKeys = new List<RegistryKey>();
                for (int i = 0; i < subKeyNames.Length - 1; i++)
                {
                    RegistryKey currentRegistryKey = default(RegistryKey);
                    if (i == 0)
                    {
                        currentRegistryKey = Registry.CurrentUser.OpenSubKey(subKeyNames[i]);
                    }
                    else
                    {
                        currentRegistryKey = registryKeys[i - 1].OpenSubKey(subKeyNames[i]);
                    }
                    registryKeys.Add(currentRegistryKey);
                    if (registryKeys.Last() != null && subKeyNames.Last() != null)
                    {
                        result = registryKeys.Last().GetValue(subKeyNames.Last());
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }

            return result;
        }

        protected int ReadInt(string subKeys)
        {
            int result = (int)this.Read(subKeys);

            return result;
        }

        protected double? ReadDouble(string subKeys)
        {
            object obj = this.Read(subKeys);
            double? result = null;
            if(obj != null)
            {
                result = double.Parse(obj.ToString());
            }           

            return result;
        }

        protected bool ReadBool(string subKeys)
        {
            bool result = default(bool);
            string resultStr = (string)this.Read(subKeys);
            if (!string.IsNullOrEmpty(resultStr))
            {
                result = bool.Parse(resultStr);
            }

            return result;
        }

        protected string ReadStr(string subKeys)
        {
            string result = string.Empty;
            string resultStr = (string)this.Read(subKeys);
            if (!string.IsNullOrEmpty(resultStr))
            {
                result = resultStr;
            }

            return result;
        }

        protected string GenerateMergedKey(params string[] keys)
        {
            string result = this.MainRegistrySubKey;
            foreach (var currentKey in keys)
            {
                result = string.Join("/", result, currentKey);                
            }

            return result;
        }

        private void CloseAllRegistryKeys(List<RegistryKey> registryKeys)
        {
            for (int i = 0; i < registryKeys.Count - 1; i++)
            {
                registryKeys[i].Close();
            }
        }
    }

MainRegistrySubKey یک کلید فرعی پیش فرض برای اپلیکیشن شما می باشد(Test Case Manager):

سپس اگر شما بخواهید یک کلید جدید با مقدار مشخص تحت TestCaseManager\Settings\Appearance ایجاد کنید باید سه کلید فرعی ایجاد کرده و سپس خود کلید را ایجاد کنید و مقدار(Value) را تنظیم کنید. با یک سرویس پایه این یک کار ساده خواهد بود. 

شما باید یک متد write با پارامترهای زیر "\Settings\Appearance\color" و مقدار رنگ به عنوان مثال red را ارسال کنید.

این کد می خواهد TestCaseManager، Settings، Appearance subKeys و color را تحت Appearance ایجاد می کند. سپس رنگ قرمز(red) را به color key اختصاص می دهد. به احتمال زیاد شما می خواهید متغیرهای خصوصی ایجاد کنید که نام های subKey مختلفی را نگه می دارد:

public class UIRegistryManager : BaseRegistryManager
    {
        private static UIRegistryManager instance;

        private readonly string themeRegistrySubKeyName = "theme";
     
        private readonly string shouldOpenDropDownOnHoverRegistrySubKeyName = "shouldOpenDropDrownOnHover";

        private readonly string titlePromptDialogRegistrySubKeyName = "titlePromptDialog";
     
        public UIRegistryManager(string mainRegistrySubKey)
        {
            this.MainRegistrySubKey = mainRegistrySubKey;
        }

        public static UIRegistryManager Instance
        {
            get
            {
                if (instance == null)
                {
                    string mainRegistrySubKey = ConfigurationManager.AppSettings["mainUIRegistrySubKey"];
                    instance = new UIRegistryManager(mainRegistrySubKey);
                }
                return instance;
            }
        }

        public void WriteCurrentTheme(string theme)
        {
            this.Write(this.GenerateMergedKey(this.themeRegistrySubKeyName), theme); 
        }

        public void WriteTitleTitlePromtDialog(string title)
        {
            this.Write(this.GenerateMergedKey(this.titlePromptDialogRegistrySubKeyName, this.titleTitlePromptDialogIsCanceledRegistrySubKeyName), title); 
        }

        public bool ReadIsCheckboxDialogSubmitted()
        {
            return this.ReadBool(this.GenerateMergedKey(this.checkboxPromptDialogIsSubmittedRegistrySubKeyName));
        }

        public string ReadTheme()
        {
            return this.ReadStr(this.GenerateMergedKey(this.themeRegistrySubKeyName));
        }
    }

شما می توانید از متد GenerateMergedKey برای ایجاد زنجیره کلید های فرعی استفاده کنید("TestCaseManager\Settings\Appearance"). کلاس پایه شامل متدهایی(ReadBool، ReadStr، ReadInt) است که داده تجزیه شده را به انواع داده ای رایج مانند bool, string, int برمی گرداند. اگر بخواهید می توانید آن را به راحتی برای برنامه خود ایجاد کنید.

آموزش سی شارپ

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان
  • C#.net
  • 4k بازدید
  • 7 تشکر

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید