السلام عليكم و رحمة الله و بركاته
رمضان مبارك على الجميع - و اعاده الله عليكم جميعاً بالخير و البركة
الموضوع يتحدث عن كيفية عمل معالج بسيط يقوم بعمل نص الاتصال برمجبا و اضافته الى مسجل النظام (Registry) .
مع امكانية اضافة بيانات اخرى مثل اسم السيرفر او قاعدة البيانات او اسم المستخدم او اي بيانات ترغب بها.
تصبح هذه البيانات متوفرة على مستوى البرنامج او على مستوى الجهاز ككل و يمكن استدعائها ببساطة.
------------------------------------------
الطريقة طرحت لطلب بعض الاخوة لها اثناء تصفحي لموضوع دورة برنامج مبيعات للاخ (ملهم).
الطريقة تنفع مع اي برنامج و هي تحل مشكلة تغيير اسم السيرفر و بالتالي تغير نص الاتصال و تطرح حل عملي لمعالجة البيانات المطلوبة بشكل متكرر من قبل البرنامج.
-------------------------------------------
في البداية سيكون لدي كود بسيط يمهد للمعلومات التي احتاجها في برنامجي .
-اسم السيرفر
-قاعدة البيانات
-اسم المستخدم الخاص بالسيرفر
-كلمة المرور
-نص الاتصال
-معلومات اخرى حسب الحاجة
-------------------------------------------
سيكون لدي دالتان , الدالة الاولى تقوم بجلب معلومات اي مفتاح (حقل) بدلالة اسمه.
الدالة الثانية تقوم باسناد بيانات لاي مفتاح (حقل) بدلالة اسمه.
هذه الحقول ستكون موجودة في الرجستري تحت عقدة خاصة نقوم بانشائها , هذه العقدة ستتوفر على حقول لكل البيانات التي نود تخزينها , دعنا نسميها جدول بيانات.
وفقاً لهذا الكلام سيكون لدينا دالة اخرى تقوم بانشاء هذه الحقول بداية اقلاع البرنامج و تعطيها قيم افتراضية فارغة , طبعاً الدالة ستفحص توفر هذه العقدة في الرجستري قبل اضافة الحقول فاذا كانت موجودة فلن تقوم بانشائها.
عملية اسناد قيم لهذه الحقول ستكون وفق نموذج خاص يجلب اسم السيرفر الخاص بالجهاز و اسم القاعدة الخاصة بالبرنامج , و يقوم بعدها بانشاء نص الاتصال و تخزينه في الحقل الموافق له في الرجستري , و كذلك تخزين باقي المعلومات التي نريدها.
باقي المعلومات يمكنك تخزينها من مواقع اخرى من البرنامج , مثل اسم المستخدم اذا كنت تستخدم نموذج دخول خاص بك في برنامجك , و كذلك اخر مستخدم ولج للبرنامج و غيرها من المعلومات التي تراها تخدم عملك (التي بدورها تصنف على انها متغيرات عامة).
فكرة تخزين المعلومات في الرجستري افضل من تخزينها في اعدادت البرنامج او في ملف نصي (بعيد عن العبث).
-------------------------------------------------------------------
نبدأ على بركة الله , بعد التقديم السابق.
-------------------------------------------------------------------
اعمل مشروع جديد و اضف له مديول (Module) سميها (Ml_ServerSetting)
اضف لها الكود التالي
الكود مشروح , اسم المجلد الذي سننشئه (MyApplication_Kyes) سيكون تحت العقدة (CurrentUser)
يحتوي المجلد على عدة حقول كما في الكود السابق يمكنك الزيادة عليها و حذف بعضها .
الدالة (CreateKeyes) هي المسؤولة عن انشاء الحقول و سنسنتخدما مع اي شاشة يبدأ بها البرنامج (هذا يعود لنمط تصميمك للبرنامج), مثل الشاشة الافتتاحية او شاشة البرنامج الرئيسية (Mdi Form).
-----------------------------------------
بعد ذلك سيكون لدينا نموذج خاص باسناد معلومات لهذه الحقول.
تصميم الواجهة سيكون مثل الصورة التالية.
النموذج يتالف من قسمين , الاول خاص باعدادت النظام , وهو يستقي معلوماته من حقول الرجستري السابقة, و يمكن الادخال فيه بشكل يدوي لاسم السيرفر و القاعدة و طريقة الدخول و اسم و كلمة المرور للمستخدم.
القسم الثاني :بيانات السيرفر من الجهاز وهو يقوم بجلب اسم السيرفر و اسم القاعدة عبر الزر(جلب) ثم يقوم باسناد المعلومات عبر الزر (اسناد).
الزر حفظ الاعدادات يقوم بتشكيل نص الاتصال و تخزين كافة المعلومات في حقول الرجستري.
-----------------------------------
الكود الخاص بالنموذج.
في الكود السابق انا ابحث عن قاعدة باسم (familycareDB) , قم بتغييرها لاسم القاعدة الخاصة بك , او عدل الشرط الخاص بجلب القواعد ليجلب لك كل القواعد و بعدها عين القاعدة كما تريد (يوجد شرح في الكود).
-----------------------------------------------------------------
لا تنسى استيراد المراجع (ManageMent.Common,ManageMent.Smo)
-------------------------------------------------------------
بعد ان اصبحت المعلومات مخزنة في حقول عامة في الرجستري , كيف يمكنني التعامل معها ؟؟؟
بكل بساطة و كما اعتدت في تعريف نص الاتصال ....
يمكنك الاستفادة من المشروع و التوسع فيه كما تحب فقط فهم الفكرة يكفي لتنطلق به في اي اتجاه و حسب حاجتك.
طريقة فحص التغييرات التي تطرأ على نص الاتصال و كيفية استدعاء المعالج السابق كما قلت سابقاً تعتمد كلياً على طريقة التصميم و البرمجة الخاصة بك.
بالنسبة لعملية اسناد معلومات لباقي الحقول , هذا يتوقف عليك فاي حقل تريد ان تسند له قيمة ما عليك الا مناداة الدالة (SetValueKey) , و عملية الحصول عل القيمة بداخلها يتم وفق الدالة (GetValueKey).
المشروع لم يخضع للتجريب المثالي نظراً لضيق الوقت , ولكن كتجربة اولى هو يعمل بشكل جيد.
بالتوفيق للجميع.
رمضان مبارك على الجميع - و اعاده الله عليكم جميعاً بالخير و البركة
الموضوع يتحدث عن كيفية عمل معالج بسيط يقوم بعمل نص الاتصال برمجبا و اضافته الى مسجل النظام (Registry) .
مع امكانية اضافة بيانات اخرى مثل اسم السيرفر او قاعدة البيانات او اسم المستخدم او اي بيانات ترغب بها.
تصبح هذه البيانات متوفرة على مستوى البرنامج او على مستوى الجهاز ككل و يمكن استدعائها ببساطة.
------------------------------------------
الطريقة طرحت لطلب بعض الاخوة لها اثناء تصفحي لموضوع دورة برنامج مبيعات للاخ (ملهم).
الطريقة تنفع مع اي برنامج و هي تحل مشكلة تغيير اسم السيرفر و بالتالي تغير نص الاتصال و تطرح حل عملي لمعالجة البيانات المطلوبة بشكل متكرر من قبل البرنامج.
-------------------------------------------
في البداية سيكون لدي كود بسيط يمهد للمعلومات التي احتاجها في برنامجي .
-اسم السيرفر
-قاعدة البيانات
-اسم المستخدم الخاص بالسيرفر
-كلمة المرور
-نص الاتصال
-معلومات اخرى حسب الحاجة
-------------------------------------------
سيكون لدي دالتان , الدالة الاولى تقوم بجلب معلومات اي مفتاح (حقل) بدلالة اسمه.
الدالة الثانية تقوم باسناد بيانات لاي مفتاح (حقل) بدلالة اسمه.
هذه الحقول ستكون موجودة في الرجستري تحت عقدة خاصة نقوم بانشائها , هذه العقدة ستتوفر على حقول لكل البيانات التي نود تخزينها , دعنا نسميها جدول بيانات.
وفقاً لهذا الكلام سيكون لدينا دالة اخرى تقوم بانشاء هذه الحقول بداية اقلاع البرنامج و تعطيها قيم افتراضية فارغة , طبعاً الدالة ستفحص توفر هذه العقدة في الرجستري قبل اضافة الحقول فاذا كانت موجودة فلن تقوم بانشائها.
عملية اسناد قيم لهذه الحقول ستكون وفق نموذج خاص يجلب اسم السيرفر الخاص بالجهاز و اسم القاعدة الخاصة بالبرنامج , و يقوم بعدها بانشاء نص الاتصال و تخزينه في الحقل الموافق له في الرجستري , و كذلك تخزين باقي المعلومات التي نريدها.
باقي المعلومات يمكنك تخزينها من مواقع اخرى من البرنامج , مثل اسم المستخدم اذا كنت تستخدم نموذج دخول خاص بك في برنامجك , و كذلك اخر مستخدم ولج للبرنامج و غيرها من المعلومات التي تراها تخدم عملك (التي بدورها تصنف على انها متغيرات عامة).
فكرة تخزين المعلومات في الرجستري افضل من تخزينها في اعدادت البرنامج او في ملف نصي (بعيد عن العبث).
-------------------------------------------------------------------
نبدأ على بركة الله , بعد التقديم السابق.
-------------------------------------------------------------------
اعمل مشروع جديد و اضف له مديول (Module) سميها (Ml_ServerSetting)
اضف لها الكود التالي
PHP كود :
Imports Microsoft.Win32
Module Ml_ServerSetting
Dim ConnectionStr As RegistryKey
Public ReadOnly MainKeyName As String = "MyApplication_Keys"
#Region "Registry Editing"
''' <summary>
''' الحصول على قيمة اي مفتاح تحت عقدة البرنامج في الرجستري
''' </summary>
''' <param name="SubKeyName">اسم المفتاح</param>
''' <returns>يعيد قيمة نصية تمثل قيمة المفتاح</returns>
Public Function GetValueKey(ByVal SubKeyName As String) As String
Dim Value As String = ""
If Not (Microsoft.Win32.Registry.CurrentUser.OpenSubKey(MainKeyName) Is Nothing) Then
Value = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(MainKeyName).OpenSubKey(SubKeyName).GetValue(SubKeyName)
Return Value
Else
Return ""
End If
Return Value
End Function
''' <summary>
''' اسناد قيمة لاي مفاح تحت عقدة البرنامج
''' </summary>
''' <param name="KeyNmae">اسم المفتاح</param>
''' <param name="Value">قيمة المفتاح</param>
Public Sub SetValueKey(ByVal KeyNmae As String, ByVal Value As String)
If Not (Microsoft.Win32.Registry.CurrentUser.OpenSubKey(MainKeyName) Is Nothing) Then
Microsoft.Win32.Registry.CurrentUser.OpenSubKey(MainKeyName, True).OpenSubKey(KeyNmae, True).SetValue(KeyNmae, Value)
End If
End Sub
''' <summary>
''' انشاء المفاتيح في مسجل النظام بداية اقلاع البرنامج للمرة الاولى في حال لم تكن موجودة
''' </summary>
Public Sub CreateKeyes()
If Registry.CurrentUser.OpenSubKey(MainKeyName) Is Nothing Then
Dim ApplicationSetting As RegistryKey = Registry.CurrentUser.CreateSubKey(MainKeyName)
ConnectionStr = ApplicationSetting.CreateSubKey("UserConnectionString") 'حقل لنص الاتصال
ConnectionStr = ApplicationSetting.CreateSubKey("ServerName") 'حقل لاسم السيرفر
ConnectionStr = ApplicationSetting.CreateSubKey("DataBaseName") 'حقل لقاعدة البيانات
ConnectionStr = ApplicationSetting.CreateSubKey("Authentication_Mode") 'حقل طريقة الدخول
ConnectionStr = ApplicationSetting.CreateSubKey("Server_UserName") 'حقل لاسم مستخدم السيرفر
ConnectionStr = ApplicationSetting.CreateSubKey("Server_Password") 'حقل كلمة المرور للسيرفر
ConnectionStr = ApplicationSetting.CreateSubKey("CurrentApp_User") 'حقل المستخدم الحالي
ConnectionStr = ApplicationSetting.CreateSubKey("Current_UserType") 'حقل لصلاحية المستخدم
ConnectionStr = ApplicationSetting.CreateSubKey("Current_UserKind") 'حقل لنوع المستخدم
ConnectionStr = ApplicationSetting.CreateSubKey("LastUserLogin") 'حقل اخر مستخدم ولج للبرنامج
DefaultSetting()
End If
End Sub
'اعدادات افتراضية
Private Sub DefaultSetting()
Try
If Not IsNothing(Registry.CurrentUser.OpenSubKey(MainKeyName)) Then
SetValueKey("UserConnectionString", "")
SetValueKey("ServerName", "")
SetValueKey("DataBaseName", "")
SetValueKey("Authentication_Mode", "")
SetValueKey("Server_UserName", "")
SetValueKey("Server_Password", "")
SetValueKey("CurrentApp_User", "")
SetValueKey("Current_UserType", "")
SetValueKey("Current_UserKind", "")
SetValueKey("LastUserLogin", "")
End If
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
#End Region
End Module
يحتوي المجلد على عدة حقول كما في الكود السابق يمكنك الزيادة عليها و حذف بعضها .
الدالة (CreateKeyes) هي المسؤولة عن انشاء الحقول و سنسنتخدما مع اي شاشة يبدأ بها البرنامج (هذا يعود لنمط تصميمك للبرنامج), مثل الشاشة الافتتاحية او شاشة البرنامج الرئيسية (Mdi Form).
-----------------------------------------
بعد ذلك سيكون لدينا نموذج خاص باسناد معلومات لهذه الحقول.
تصميم الواجهة سيكون مثل الصورة التالية.
النموذج يتالف من قسمين , الاول خاص باعدادت النظام , وهو يستقي معلوماته من حقول الرجستري السابقة, و يمكن الادخال فيه بشكل يدوي لاسم السيرفر و القاعدة و طريقة الدخول و اسم و كلمة المرور للمستخدم.
القسم الثاني :بيانات السيرفر من الجهاز وهو يقوم بجلب اسم السيرفر و اسم القاعدة عبر الزر(جلب) ثم يقوم باسناد المعلومات عبر الزر (اسناد).
الزر حفظ الاعدادات يقوم بتشكيل نص الاتصال و تخزين كافة المعلومات في حقول الرجستري.
-----------------------------------
الكود الخاص بالنموذج.
PHP كود :
Imports Microsoft.SqlServer.Management.Common
Imports Microsoft.SqlServer.Management.Smo
Public Class Fr_Setting
Private Sub Rd_WindowsAuth_CheckedChanged(sender As Object, e As EventArgs) Handles Rd_WindowsAuth.CheckedChanged
If Rd_WindowsAuth.Checked = True Then
Txt_UserName.ReadOnly = True
Txt_UserPwd.ReadOnly = True
End If
End Sub
Private Sub Rd_SqlAuth_CheckedChanged(sender As Object, e As EventArgs) Handles Rd_SqlAuth.CheckedChanged
If Rd_SqlAuth.Checked = True Then
Txt_UserName.ReadOnly = False
Txt_UserPwd.ReadOnly = False
End If
End Sub
Private Sub Fr_Setting_Load(sender As Object, e As EventArgs) Handles MyBase.Load
GetAllSettings()
End Sub
Private Sub GetAllSettings()
If Not (Microsoft.Win32.Registry.CurrentUser.OpenSubKey(MainKeyName) Is Nothing) Then
Txt_ServerName.Text = If(GetValueKey("ServerName") <> String.Empty, GetValueKey("ServerName"), String.Empty)
Txt_DatabaseName.Text = If(GetValueKey("DataBaseName") <> String.Empty, GetValueKey("DataBaseName"), String.Empty)
'
Dim Mode As String = GetValueKey("Authentication_Mode")
If Mode = "Windows Authentication" Then
Rd_WindowsAuth.Checked = True
ElseIf Mode = "SQL Server Authentication" Then
Rd_SqlAuth.Checked = True
Else
Rd_WindowsAuth.Checked = True
End If
Txt_UserName.Text = If(GetValueKey("Server_UserName") <> String.Empty, GetValueKey("Server_UserName"), String.Empty)
Txt_UserPwd.Text = If(GetValueKey("Server_Password") <> String.Empty, GetValueKey("Server_Password"), String.Empty)
TXt_ConnectionString.Text = If(GetValueKey("UserConnectionString") <> String.Empty, GetValueKey("UserConnectionString"), String.Empty)
End If
End Sub
Private Sub Save_Settings()
If String.IsNullOrEmpty(Txt_ServerName.Text) Or String.IsNullOrEmpty(Txt_DatabaseName.Text) Then
MessageBox.Show("لا يتوفر سيرفر او قاعدة بالاسماء المطلوبة", "تنبيه", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Exit Sub
End If
Try
If Not (Microsoft.Win32.Registry.CurrentUser.OpenSubKey(MainKeyName) Is Nothing) Then
TXt_ConnectionString.Clear()
SetValueKey("ServerName", Txt_ServerName.Text)
SetValueKey("DataBaseName", Txt_DatabaseName.Text)
'
If Rd_WindowsAuth.Checked = True Then
Txt_UserName.Clear()
Txt_UserPwd.Clear()
'
SetValueKey("Authentication_Mode", "Windows Authentication")
CreateConnection(Txt_ServerName.Text, Txt_DatabaseName.Text)
SetValueKey("UserConnectionString", TXt_ConnectionString.Text)
SetValueKey("Server_UserName", String.Empty)
SetValueKey("Server_Password", String.Empty)
MessageBox.Show("تم الحفظ", "تنبيه", MessageBoxButtons.OK, MessageBoxIcon.Information)
ElseIf Rd_SqlAuth.Checked = True Then
SetValueKey("Authentication_Mode", "SQL Server Authentication")
CreateConnection(Txt_ServerName.Text, Txt_DatabaseName.Text, Txt_UserName.Text, Txt_UserPwd.Text)
SetValueKey("UserConnectionString", TXt_ConnectionString.Text)
SetValueKey("Server_UserName", Txt_UserName.Text)
SetValueKey("Server_Password", Txt_UserPwd.Text)
MessageBox.Show("تم الحفظ", "تنبيه", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End If
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub Btn_Save_Click(sender As Object, e As EventArgs) Handles Btn_Save.Click
Save_Settings()
End Sub
Private Function CreateConnection(ByVal ServerName As String, ByVal DataBaseName As String, Optional ByVal UserNmae As String = Nothing, Optional ByVal Password As String = Nothing) As String
If UserNmae = Nothing Or Password = Nothing Then
Dim Windows_Connection As String = "Data Source = " & ServerName & ";Initial Catalog=" & DataBaseName & ";Integrated Security=True"
TXt_ConnectionString.Text = Windows_Connection
Return Windows_Connection
Else
Dim Sql_Connection As String = "Data Source = " & ServerName & ";Initial Catalog=" & DataBaseName & ";User ID=" & UserNmae & ";Password=" & Password
TXt_ConnectionString.Text = Sql_Connection
Return Sql_Connection
End If
End Function
Private Sub Btn_Close_Click(sender As Object, e As EventArgs) Handles Btn_Close.Click
Close()
End Sub
#Region "Server Setting"
Dim conn As New ServerConnection()
Dim srv As New Server()
'جلب قائمة السيرفرات
Private Sub GetServerList()
Dim Server As String = String.Empty
Dim instance As Sql.SqlDataSourceEnumerator = Sql.SqlDataSourceEnumerator.Instance
Dim table As System.Data.DataTable = instance.GetDataSources()
For Each row As System.Data.DataRow In table.Rows
Server = String.Empty
Server = row("ServerName")
If row("InstanceName").ToString.Length > 0 Then
Server = Server & "\" & row("InstanceName")
End If
LstSrv.Items.Add(Server)
Next
LstSrv.SelectedIndex = LstSrv.FindStringExact(Environment.MachineName)
End Sub
''' <summary>
''' تحميل القواعد باستثناء قواعد النظام
''' </summary>
''' <remarks></remarks>
Private Sub LoadDbs()
Me.Cursor = Cursors.WaitCursor
GetServerList()
'
If LstSrv.Items.Count > 0 Then
LstSrv.SelectedIndex = 0
conn = New ServerConnection(LstSrv.SelectedItem.ToString)
srv = New Server(conn)
End If
'تحميل القاعدة المطلوبة فقط
'بامكانك تحميل كل القواعد بعد ازالة الشرط
Try
'=================
LstDbs.Items.Clear()
For Each db As Database In srv.Databases
If Not db.IsSystemObject And db.Name = "familycareDB" Then
LstDbs.Items.Add(db.Name)
End If
Next
'
If LstDbs.Items.Count > 0 Then
LstDbs.SelectedIndex = LstDbs.FindStringExact("familycareDB")
End If
'
Catch ox As SmoException
MsgBox(ox.Message.ToString)
Catch ex As Exception
MsgBox(ex.Message.ToString)
Finally
Me.Cursor = Cursors.Default
If srv.ConnectionContext.IsOpen Then
srv.ConnectionContext.Disconnect()
End If
End Try
End Sub
'جلب بيانات السيرفر و القاعدة من الجهاز
Private Sub Btn_GetInfo_Click(sender As Object, e As EventArgs) Handles Btn_GetInfo.Click
LoadDbs()
End Sub
'اسناد المعلومات بعد جلبها
Private Sub Btn_LoadInfo_Click(sender As Object, e As EventArgs) Handles Btn_LoadInfo.Click
If Not String.IsNullOrEmpty(LstSrv.Text) Then
Txt_ServerName.Text = LstSrv.Text
End If
If Not String.IsNullOrEmpty(LstDbs.Text) Then
Txt_DatabaseName.Text = LstDbs.Text
End If
End Sub
#End Region
End Class
-----------------------------------------------------------------
لا تنسى استيراد المراجع (ManageMent.Common,ManageMent.Smo)
-------------------------------------------------------------
بعد ان اصبحت المعلومات مخزنة في حقول عامة في الرجستري , كيف يمكنني التعامل معها ؟؟؟
بكل بساطة و كما اعتدت في تعريف نص الاتصال ....
PHP كود :
Public Shared SqlCon As SqlConnection
Private ConnectionString As String = GetValueKey("UserConnectionString")
PHP كود :
Public Sub New()
If Not String.IsNullOrEmpty(ConnectionString) Then
SqlCon = New SqlConnection(ConnectionString)
Else
MessageBox.Show("نص الاتصال بالسيرفر مفقود", "تنبيه", MessageBoxButtons.OK, MessageBoxIcon.Information)
OpenSetting()
End If
End Sub
PHP كود :
Private Sub OpenSetting()
Dim Fr_Setting As New Fr_Setting
With Fr_Setting
.Owner = Frm_Main
.StartPosition = FormStartPosition.CenterScreen
.ShowDialog()
SqlCon = New SqlConnection(GetValueKey("UserConnectionString"))
End With
End Sub
طريقة فحص التغييرات التي تطرأ على نص الاتصال و كيفية استدعاء المعالج السابق كما قلت سابقاً تعتمد كلياً على طريقة التصميم و البرمجة الخاصة بك.
بالنسبة لعملية اسناد معلومات لباقي الحقول , هذا يتوقف عليك فاي حقل تريد ان تسند له قيمة ما عليك الا مناداة الدالة (SetValueKey) , و عملية الحصول عل القيمة بداخلها يتم وفق الدالة (GetValueKey).
المشروع لم يخضع للتجريب المثالي نظراً لضيق الوقت , ولكن كتجربة اولى هو يعمل بشكل جيد.
بالتوفيق للجميع.
اللهم لك الحمد كما ينبغي لجلال وجهك و عظيم سلطانك
في حل و ترحال