السلام عليكم و رحمة الله تعالى و بركاته,,,
هذا الموضوع, إن شاء الله, سيكون مخصصا لأكواد التعامل مع Windows Registry. لاحظت مع إصدارات إطار الدوت نت نوعا من الإبتعاد عن تسجيل ويندوز حيث بعد أن كانت عملية تسجيل تكوين البرامج المطورة بـ VB 6 و ماقبلها سهلا و مدعوما على تسجيل ويندوز, نرى أن إصدارات VB.NET تحولت إلى التسجيل على ملف التكوين من نوع XML الذي يحدد عن طريق النافذة Settings. و مع هذا, لا زال تسجيل ويندوز القلب النابض لكل إصدارات نظام التشغيل ويندوز و لا تكاد تطور مشروعا بدون الحاجة إلى تفقد تسجيل ويندوز و قراءة المعلومات منه. لدي تصور لمراحل هذا الموضوع و لكن أفضل عدم الإفصاح عنها الآن. مبدأ الوعد بالقليل لإعطاء الكثير ;)
في هذا الجزء الأول, سنتحدث إن شاء الله عن كيفية البحث داخل Windows Registry. سنتحدث عن طريقة بسيطة لإدماج البحث داخل الويندوز ريجستري على مشروعاتكم. سنبدأ في هذا الجزء الأول مع دوال بسيطة تقوم بعملية البحث. سنطور هذه الدوال في الجزء الثاني إلى فئة قابلة لإعادة الاستعمال في أي مشروع VB.NET. لا أعرف إن كان أحدنا سيحتاج هذا الكود يوما ما في حياته البرمجية لكن أظن أن المعرفة بالشيء خير من الجهل به.
تسجيل ويندوز أو Windows registry هو مستودع مركزي لبيانات نظام التشغيل و البرامج التي تعمل عليه. هذا التسجيل له هيكل هرمي موجه للتصنيف المنطقي للمعلومات المخزنة. محتوى التسجيل منظم على شكل مجلدات و ملفات و بيانات كما هو الحال بالنسبة للبرنامج مستكشف ويندوز. حيث المجلدات هي المفاتيح و الملفات هي أسماء القيم التي تحتوي على البيانات المخزنة. التسلسل الهرمي لتسجيل الويندوز يتمحور على مفاتيح أساسية لكل منها دورها و المعلومات التي تخزنها و يمكن تعريفها كالتالي :
HKEY_CURRENT_USER : جذر مفاتيح معلومات المستخدم الذي تم تسجيل دخوله حاليا. و تحتوي المفاتيح الداخلية على معلومات حول مجلدات المستخدم, إعدادات لوحة التحكم, إعدادات الشاشة و غيرها من المعلومات حساب المستخدم الحالي.
HKEY_USERS : جذر مفاتيح معلومات كل مستخدمي ويندوز الذين لهم حساب على الحاسوب. و كل مفتاح داخلي من المستوى الأول يخص مستخدما منهم.
HKEY_LOCAL_MACHINE : جذر مفاتيح تحوي معلومات التكوين لجهاز الحاسوب. هذه المعلومات مشتركة بين المستخدمين و عامة بالنسبة للحاسوب.
HKEY_CLASSES_ROOT : جذر مفاتيح تحوي مفاتيح لكل نوع من أنواع الملفات المسجلة على نظام التشغيل. هذه المفاتيح تستعمل من طرف مستكشف ويندوز للوصول إلى البرنامج المحرر الافتراضي لنوع الملف المطلوب.
HKEY_CURRENT_CONFIG : جذر مفاتيح تحوي مفاتيح معلومات حول التشكيل الجانبي الحالي للحاسوب.
بعد هذه النبذة الموجزة عن تسجيل ويندوز و قبل البدء في استعراض الكود, لابد من التعرف على البرنامج المرفق. FindReg يقوم بالبحث عن كلمة داخل تسجيل الويندوز. يمكن البرنامج المستخدم من اختيار المفاتيح الجذور التي يتم البحث داخلها. كلما وجد عنصرا كان مفتاحا, قيمة أو اسم لقيمة يقوم بزيادة مسار المفتاح الذي وجد بداخله. يمكن للمستخدم فتح البرنامج regedit.exe على المفتاح المختار من على لائحة العناصر الموجودة أثناء البحث بالنقر مرتين على العنصر من اللائحة أو النقر على الزر ]افتح[. يمكن للمستخدم بدء عملية البحث بالنقر على الزر ]ابحث[ و إيقاف البحث متى شاء بالنقر على الزر ]إيقاف البحث[.
الدالة التي سنقوم بدراستها غير قابلة لإعادة الاستعمال بل معدة فقط للعمل داخل المشروع المرفق و الذي يمثل برنامجا صغيرا للبحث داخل Windows Registry. الدالة FindNext دالة عودية تقوم بالبحث داخل مفتاح عن مفاتيح و قيم و أسماء قيم. فتقوم بالبحث أولا عن القيم و أسماء القيم التي يحتوي عليها المفتاح الذي تم تمريره للدالة للبحث داخله. بعد ذلك تقوم الدالة باستعراض المفاتيح الداخلية و المناداة على نفسها للبحث داخل كل مفتاح موجود داخل المفتاح الذي تم تمريره للبحث فيه. و قبل استعراض الكود, لابد لنا من وقفة مع الكائن RegistryKey. الكائنات من نوع هذه الفئة تمكننا من التعامل مع مفتاح تسجيل ويندوز و محتوياته حيث الخاصية Name تمكننا من الوصول إلى مسار المفتاح. الخاصية SubKeyCount تعطينا عدد المفاتيح الداخلية للمفتاح. الخاصية ValueCount تعطينا عدد القيم التي يحويها المفتاح. الدالة GetSubKeyNames ترجع لنا مصفوفة من كائنات string كل واحدة تمثل اسم مفتاح داخلي. الدالة GetValueNames ترجع لنا مصفوفة من كائنات string كل واحد اسم القيمة التي يمكن أن نمررها إلى الدالة GetValue للحصول على قيمتها. و لا ننسى في الأخير أنه للوصول إلى مفتاح يجب أن نقوم بعملية فتحه بالمناداة على الدالة OpenSubKey و تمرير اسم و مسار المفتاح المراد فتحه و لا ننسى عملية الغلق بعد الفتح حتى لا نتسبب في هدر موارد النظام. الدوال و الخصائص الأخرى سوف نتطرق لها في الأجزاء القادمة إن شاء الله.
فيما يلي كود الدالة FindNext معلق عليه للمزيد من الفهم :
' الدالة التي تبحث داخل مفاتيح الريجيستري
' rkRoot : الذي تبدأ منه عملية البحث RegistryKey كائن من نوع
' path : المسار الذي تبدأ منه عملية البحث
Private Sub FindNext(ByVal rkRoot As RegistryKey, ByVal path As String)
If path = "" Then Return
' المستخدم أمر بوقف البحث
If NeedStop Then Return
' محاولة الوصول إلى المفتاح
Dim rk As RegistryKey
Try
rk = rkRoot.OpenSubKey(path)
Catch
Return ' لا نتوفر على أذونات للبحث في هذا المفتاح
End Try
' المفتاح فارغ
If rk Is Nothing Then Return
' إخبار المستخدم بالمفتاح الدي نبحث فيه الآن
statusLabel.Text = rk.Name
' لتبسيط البرنامج لن نستعمل مسارا خاصا بالبحث
Application.DoEvents()
' Values : names and data
If rk.ValueCount > 0 Then
' الوصول إلى لائحة القيم و أسمائها
Dim valueCol As String() = rk.GetValueNames()
For Each s As String In valueCol
' المناداة على الدوال التي تتأكد من القيم و أسمائها
If ValueCheckBox.Checked Then CheckRegValueName(rk.Name, s)
If DataCheckBox.Checked Then
Dim oValue As Object = rk.GetValue(s)
If Not (oValue Is Nothing) Then CheckRegValueData(rk.Name, s, oValue.ToString())
End If
Next
End If
' Key names
If rk.SubKeyCount > 0 Then
' الوصول إلى المفاتيح
Dim keys As String() = rk.GetSubKeyNames()
For Each s As String In keys
If KeyCheckBox.Checked Then CheckRegKeyName(rk.Name, s)
' إلى المفتاح التالي
Dim nextPath As String = rk.Name + "\" + s
nextPath = nextPath.Replace("\\", "\")
FindNext(rkRoot, nextPath.Substring(nextPath.IndexOf("\") + 1))
Next
End If
' غلق المفتاح قبل الخروج
rk.Close()
End Subعند تشغيل عملية البحث, نمرر للدالة FindNext كائن من نوع RegistryKey يمثل المفتاح الجذر الذي سنبدأ منه عملية البحث. البارامتر path سنمرر من خلاله مسار المفتاح الداخلي الذي ستبدأ الدالة FindNext بالبحث فيه. فمثلا لبدء البحث من جذر المفتاح الأساسي HKEY_CURRENT_USER سننادي على الدالة FindNext بالشكل التالي :
FindNext(Registry.CurrentUser, "\")
الدالة FindNext تستعمل دوال أخرى :
CheckRegKeyName : تتحقق من توفر شروط البحث في المفتاح الحالي.
CheckRegValueName : تتحقق من توفر شروط البحث في اسم القيمة الحالي.
CheckRegValueData : تتحقق من توفر شروط البحث في بيانات القيمة الحالية.
الكود في حالته هاته ليس معدا لإعادة استعمال الكود في مشاريع أخرى. و قد يحتاج للوقت لتحريره للعمل في مشروع آخر. في الجزء التالي, سننشئ فئة معدة لإعادة الاستعمال في أي مشروع. ستكون إن شاء الله, فئة من نوع Component لتسهيل زيادتها على نماذج Form و تحديد خصائصها و أحداثها أوتوماتيكيا عن طريق نافذة الخصائص.
بقي شيء تجدر الإشارة إليه. ألا وهو كود صغير يمكن من تشغيل محرر تسجيل ويندوز و فتحه مفتاحا نحدده عند ظهور نافذة البرنامج. هذا هو الكود :
' عند التشغيل regedit تحديد المفتاح الذي سيفتح عليه
Dim rk As RegistryKey = Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Applets\Regedit", True)
rk.SetValue("LastKey", FindListBox.Items(FindListBox.SelectedIndex).ToString())
rk.Close()
' تشغيل regedit.exe
Shell("cmd /c regedit.exe")هذا الكود يكتب مسار المفتاح المراد فتحه عند تشغيل محرر تسجيل ويندوز داخل المفتاح HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Applets\Regeditعلى القيمة LastKey ثم يقوم بتشغيل البرنامج الذي سيفتح و يظهر المفتاح عند أول ظهور.
تحياتي...