اذهب إلى المحتوى

حسام برهان

الأعضاء
  • المساهمات

    215
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    31

كل منشورات العضو حسام برهان

  1. أهلًا وسهلًا، السبب في هذه المشكلة أنّك كنت تستخدم ترميز ascii وهو غير ملائم للغات المختلفة عن اللغة الانجليزية، حيث لا يستطيع تمثيل الأحرف الخاصة التي لا توجد في أبجدية اللغة الانجليزية.
  2. هل من الممكن أن تحدد نوع التطبيق الذي تعمل عليه، وأي معلومات إضافية من فضلك.
  3. استخدم تنسيقات CSS التالية: iframe { margin: 0 auto; background-color: #777; display:block; } مع الانتباه إلى أهميّة القاعدتين display:block و margin: 0 auto. في حين أنّني وضعت لون الخلفية لتمييزه فقط.
  4. جرب استخدام القيمة utf8_unicode_ci كنوع collation لكل حقل من الحقول التي ستخزّن فيها هذه الأخرف الخاصة.
  5. إذًا أنت تعمل على ASP.NET Web Forms علمت ذلك لأنّك أخبرتني أنّك تستخدم UpdatePanel. على العموم المشكلة في ذلك أنّ تطبيقات الويب عمومًا لا تحافظ على الحالة الحاليّة لها Stateless. فأي متغيّر تعدّل قيمته عند طلب Request معيّن، سيزول تأثير هذا التعديل عندما تنتهي معالجة الطلب. وهكذا فالعدد الثابت الذي يعرضه برنامجك (القيمة 2) منطقية تمامًا. احدى الحلول المتاحة لهذه المشكلة تكمن في استخدام طريقة تحافظ فيها على حالة التطبيق بين الطلبات المتتالية (قيمة المتغيّر posts_num على وجه التحديد). الطريقة التي اخترتها لك هي استخدام الخاصيّة Session من الصنف Page والتي تحافظ على قيمة المتغيّر posts_num. انظر إلى التعديل التالي الذي يجب أن تنجزه على شيفرتك: protected void loadMore_btn_ServerClick(object sender, EventArgs e) { int posts_num; if (Session["CurrentPostValue"] == null) { posts_num = 1; } else { posts_num = (int)Session["CurrentPostValue"]; } counter_lbl.Text = posts_num.ToString(); posts_num++; Session["CurrentPostValue"] = posts_num; } لاحظ أنّ المتغيّر posts_num أصبح محليًّا local variable ولم يعد موجودًا على مستوى الصنف.
  6. لغة XML هي اختصار للكلمات التالية: EXtensible Markup Language وتعني لغة الرُماز الموسّعة. صمّمت هذه اللغة البسيطة كي تكون معيارًا موحّدًا لنقل البيانات بين التطبيقات المختلفة مهما كانت أنواعها وبصرف النظر عن أنظمة التشغيل التي تعمل عليها. تعتمد XML على قواعد بسيطة يمكنك أن تفهمها بسرعة. انظر مثلًا للبنية التالية المكتوبة باستخدام XML والتي تُعبّر عن بيانات بسيطة لمجموعة من الطلاب: <Students> <Student> <FirstName>Ahmad</FirstName> <LastName>Saed</LastName> <Mark>60</Mark> </Student> <Student> <FirstName>Mamduh</FirstName> <LastName>Murad</LastName> <Mark>80</Mark> </Student> <Student> <FirstName>Ayman</FirstName> <LastName>Mohammad</LastName> <Mark>98</Mark> </Student> </Students> أتوقّع أنّه بتأمّل بسيط ستعلم عدد الطلاب وأسماؤهم ودرجاتهم أيضًا. يمكنك تعلّم XML بشكل متكامل عن طريق هذه السلسلة التعليميّة.
  7. جهزنا في الدرس السابق خادوم قاعدة البيانات وعملنا على ضمّه إلى المجال hsoub-sp.com. سنتابع عملنا في سلسلة تنصيب شير بوينت، حيث سنقوم في هذا الدرس بتنصيب SQL Server 2012 على خادوم قاعدة البيانات الذي جهزناه في الدرس السابق. سنبدأ الدرس بإضافة حساب جديد إلى الدليل النشط ضمن خادوم المتحكّم بالمجال Domain Controller، يُعتبر هذا الحساب مسؤولًا عن إدارة الخدمات services الخاصّة بـ SQL Server. بعد ذلك نبدأ عمليّة التنصيب. إضافة الحساب SPSQLService إلى الدليل النشط انتقل إلى خادوم المتحكّم بالمجال HSB-DC، وسجّل الدخول باسم مدير المجال SPAdmin. بعد تسجيل الدخول انقر زر ابدأ لتظهر صفحة البداية، ثمّ اكتب مباشرةً العبارة التالية: Active Directory Users and Computers ستظهر نافذة الدليل النشط لإدارة المستخدمين والحواسيب ضمن المجال hsoub-sp.com. من الجانب الأيسر للنافذة، انتقل إلى المستخدمين Users ثم انقر بزر الفأرة الأيمن واختر New، ومن القائمة الفرعية التي ستظهر، اختر User كما في الشكل التالي تمامًا: بعد نقر User ستظهر النافذة المسؤولة عن إضافة مستخدم جديد. سنختار الاسم SPSQLService له، كما في الشكل التالي: انقر بعد ذلك الزر Next لكتابة كلمة مرور مناسبة، واحرص على أن تكون صناديق الاختيار مطابقة تمامًا لما يظهر في الشكل التالي: انقر Next لتظهر لك النافذة الأخيرة التي تعرض ملخّص بسيط لما ستقوم به، ثم انقر زر Finish ليتم إنشاء المستخدم SPSQLService. تنصيب SQL Server 2012 سنبدأ الآن بعمليّة تنصيب التطبيق SQL Server 2012. انتقل إلى خادوم قاعدة البيانات HSB-DB، وسجّل الدخول إلى ويندوز باستخدام الحساب HSOUB-SP\SPAdmin. وأحبّ أن أنوّه إلى ضرورة أن يكون خادوم قاعدة البيانات متصلًا بالإنترنت عند هذه المرحلة، لأنّ برنامج الإعداد سيحتاج للإنترنت للبحث عن تحديثات جديدة أثناء عمليّة التنصيب. ملاحظة في بعض الحالات قد يطلب منك برنامج الإعداد إضافة إطار العمل .NET Framework 3.5 Features وهو عبارة عن ميزة من الممكن إضافتها من Windows Server 2012 من برنامج إدارة الخادوم Server Manager. حيث يمكنك نقر القائمة Manage ثم اختيار Add Roles and Features، وبعد أن تظهر نافذة "قبل أن تبدأ" Before you begin يمكنك نقر زر Next لتنتقل إلى نافذة اختيار نمط التنصيب Select installation type. اترك الإعدادات الافتراضيّة كما هي وانقر زر Next للانتقال إلى نافذة اختيار الخادوم المستهدف Select destination server، تأكّد أنّ سنجري التنصيب على الخادوم HSB-DB من القائمة في الأسفل، ثمّ انقر Next. سننتقل إلى نافذة اختيار الأدوار Select server roles وهنا لا نريد أيضًا إجراء أيّة تعديلات، لذلك فانقر Next. ستصل بعد ذلك إلى نافذة اختيار المزايا Select features. ستجد الميّزة .NET Framework 3.5 Features أوّل القائمة. انشر لترى محتويات هذه الميّزة، وضع علامة على صندوق الاختيار بجوار .NET Framework 3.5 (includes .NET 2.0 and 3.0) ثم انقر Next وتابع عمليّة التقدّم لتُنهي عمليّة إضافة هذه الميزة. أدخل قرص تطبيقSQL Server 2012 (يمكنك تحميل نسخة تجريبيّة منه من هنا)، ثمّ شغّل برنامج الإعداد Setup.exe سيستغرق الأمر قليلًا من الوقت حتى تظهر النافذة الرئيسيّة لبرنامج الإعداد. من الجهة اليسرى لهذه النافذة، انقر على تنصيب Installation لتظهر لك في الجهة اليمنى من هذه النافذة الخيارات المتاحة للتنصيب. انقر الخيار الأوّل: New SQL Server stand-alone installation or add features to an existing installation وذلك لإنشاء نسخة جديدة من SQL Server. سيعمل برنامج الإعداد عندئذٍ على إجراء بعض الاختبارات التي تسبق عمليّة التنصيب من خلال النافذة Setup Support Rules. لن يطور الأمر كثيرًا حتى تحصل على ما يشبه الشكل التالي: يشير ذلك إلى نجاح هذه الاختبارات على الخادوم. انقر زر OK للانتقال إلى نافذة البحث عن تحديثات جديدة لـ SQL Server، سيأخذ برنامج الإعداد بعض الوقت في البحث عن التحديثات المتوفّرة، وبعد الانتهاء انقر زر Next لتبدأ عمليّة تحميل ملفات التنصيب: بعد الانتهاء سينتقل برنامج الإعداد مرّة أخرة إلى النافذة Setup Support Rules التي تختبر المشاكل التي قد تعترض عمليّة تنصيب SQL Server. بعد الانتهاء من الاختبار ستحصل على شكل شبيه بالشكل التالي علمًا أنّه في حال الحصول على أيّ إخفاق Failed يجب تصحيحه قبل المتابعة. انقر Next للاختيار بين تنصيب نسخة تجريبيّة Evaluation أو أن تُدخل رقم المنتج Product key في حال كان لديك نسخة أصليّة: بعد اختيار التنصيب المناسب لك، انقر زر Next للانتقال إلى اتفاقيّة الترخيص. ضع علامة على صندوق الاختيار I accept the license terms ثم انقر Next لتنتقل إلى النافذة Setup Role والتي يتمّ من خلالها اختيار المزايا الأساسيّة التي ستُنصّب مع SQL Server. اختر SQL Server Feature Installation وانقر Next كما في الشكل التالي: سننتقل إلى نافذة اختيار المزايا الفرعيّة التي نرغب بتضمينها مع SQL Server. سنختار من هذه المزايا ما هو ضروري لعملنا فقط. اختر من البنية الشجريّة التي تظهر أمامك ما يلي: Database Engine Services Full-Text and Semantic Extractions for Search Management Tools – Basic Management Tools – Complete علمًا أنّه ستحتاج إلى استخدام شريط التمرير لتجد جميع المزايا السابقة. انظر إلى الشكل التالي: انقر الزر Next، سيأخذ برنامج الإعداد وقتًا قليلًا ليجري اختبارًا سريعًا يحدّد من خلاله إمكانيّة المتابعة مع المزايا التي قمنا باختيارها قبل قليل. ستحصل على شكل شبيه بما يلي: انقر الزر Next للانتقال إلى نافذة Instance Configuration. لا نريد إجراء أي تعديلات هنا، لذلك فانقر الزر Next. لينتقل برنامج الإعداد بعدها إلى نافذة اختبار وجود مساحة كافية على القرص الصلب لتنصيب SQL Server مع المزايا المختارة. في حال توفّر هذه المساحة انقر زر Next. سننتقل الآن إلى نافذة إعداد الخادوم Server Configuration. سنجري هنا بعض التعديلات المهمّة. انظر إلى الشكل التالي: يعمل SQL Server على شكل خدمات Services ضمن ويندوز. تعرض النافذة السابقة الخدمات الأربع التي تشغّل SQL Server وهي: SQL Server Agent SQL Server Database Engine SQL Full-text Filter Daemon Launcher SQL Server Browser تحتاج كل خدمة من الخدمات السابقة إلى حساب مستخدم ذي صلاحيّات مناسبة لكي تعمل. يُسند برنامج الإعداد حساب مستخدم افتراضي لكل خدمة. ولكنّنا وبما أننا نعمل ضمن المجال hsoub-sp.com لذلك سنختار المستخدم SPSQLService الذي أنشأناه في مطلع هذا الدرس ليكون الحساب المرتبط بالخدمتين: SQL Server Agent SQL Server Database Engine وذلك من خلال ما يلي: من أجل الخدمة SQL Server Agent انتقل إلى العمود Account Name الخاص بها ثم اكتب: HSOUB-SP\SPSQLService ثم انتقل إلى عمود كلمة المرور Password لتُدخل كلمة المرور الخاصّة بهذا الحساب. كرّر نفس العمليّة تمامًا بالنسبة إلى الخدمة SQL Server Database Engine. كما في الشكل التالي: انقر بعد ذلك زر Next لتصل إلى نافذة إعداد محرّك قاعدة البيانات Database Engine Configuration. كما في الشكل التالي: نحتاج أولًا إلى نقر الزر Add Current User من الأسفل لإضافة حساب مدير المجال SPAdmin. لاحظ أيضًا أنّنا نريد استخدام استيثاق ويندوز Windows authentication للاتصال بـ SQL Server. يمكنك أن تلاحظ أيضًا وجود لسان Data Directories لتحديد مسارات المجلّدات التي ستُستخدم لحفظ ملفّات قواعد البيانات. يمكنك تغيير المسارات الافتراضيّة لحفظ ملفّات قواعد البيانات ضمن مجلّدات مختلفة (أنصح بذلك) بشرط أن يكون لهذه المجلّدات قابليّة القراءة والكتابة. يمكنك اختيار محرّك أقراص مختلف من القرص الصلب، أو يمكنك أن تختار قرص صلب مختلف بالكامل في حال كان هذا الخادوم يحتوي على مثل هذا القرص. انقر Next لينتقل برنامج الإعداد إلى نافذة التقرير عن وجود أخطاء Error Reporting والتي تسمح لـ SQL Server أن يُرسل رسائل الأخطاء مباشرةً إلى مايكروسوفت في حال حدوثها. انقر زر Next لإجراء اختبار نهائي قبل البدء بعمليّة التثبيت. في حال نجح هذا الاختبار يمكنك نقر زر Next مجدّدًا للانتقال إلى النافذة الأخيرة قبل البدء بعمليّة التنصيب وهي Ready to Install التي تعرض تقريرًا بالمهام التي سيجريها برنامج الإعداد. ألق نظرةً عليها ثم انقر الزر Install لتبدأ عمليّة التنصيب. ستأخذ عمليّة التنصيب بعض الوقت حتى تنتهي. ستحصل على شكل شبيه بما يلي. انقر الزر Close. ضبط بعض الإعدادات لـ SQL Server بعد الانتهاء من عمليّة التنصيب لابدّ من ضبط خاصيّة المعالجة المتوازيّة لـ SQL Server لكي يتمكّن من تخديم شير بوينت بشكل صحيح. انقر زر ابدأ لتظهر صفحة البداية، ثم اكتب مباشرةً ما يلي: SQL Server Management Studio لتظهر نتيجة البحث المطلوبة بنفس الاسم السابق. انقرها ليعمل برنامج إدارة SQL Server. حيث سيطلب منك في البداية تسجيل الدخول إليه كما في الشكل التالي: لا تقم بأيّ تعديل هنا، انقر زر اتصال Connect للاتصال بـ SQL Server. من نافذة مستعرض الكائنات Object Explorer من الجهة اليسرى، انقر بزر الفأرة الأيمن على الجذر الرئيسي HSB-DB واختر Properties الموجودة آخر القائمة. ستظهر نافذة الخصائص Properties لـ SQL Server. من الجهة اليسرى انتقل إلى الصفحة Advanced ليتم تحديث محتويات القسم الأيمن. انتقل إلى الخاصيّة Max Degree of Parallelism (ستحتاج إلى استخدام شريط التمرير)، لاحظ أنّها تحمل القيمة 0. غيّر هذه القيمة لتصبح 1، كما في الشكل التالي: انقر موافق، ثم أغلق برنامج إدارة SQL Server. انقر زر ابدأ من جديد لتظهر صفحة البداية، ثم اكتب مباشرةً ما يلي: SQL Server Configuration Manager وهو برنامج مدير إعدادات SQL Server، انقر نتيجة البحث لتظهر نافذة البرنامج. من الجهة اليسرى لها، انقر SQL Server Services لتظهر الخدمات الموافقة في الجهة اليمنى من النافذة. كما في الشكل التالي: نلاحظ أنّ الخدمة SQL Server Browser متوقّفة عن العمل (لاحظ المربّع الأحمر الصغير الذي يظهر بجوارها). انقر الآن بزر الفأرة الأيمن على SQL Server Browser واختر Properties. ستظهر نافذة الخصائص، انقر على اللسان Service كما في الشكل التالي: انتقل إلى الخاصيّة Start Mode لاحظ أنّها تحمل القيمة Disabled أي أنّ هذه الخدمة ستكون غير مفعّلة disabled بشكل افتراضيّ. غيّر هذه القيمة لتصبح Automatic ثم انقر OK. ستنتقل إلى النافذة الأساسيّة. انقر بزر الفأرة الأيمن من جديد على SQL Server Browser واختر Start لتشغيل هذه الخدمة: بعد ذلك انشر SQL Native Client 11.0 Configuration (32 bit) من الجهة اليسرى، ثم انقر Client Protocols وتأكّد أنّ الإعدادات التي ستظهر في الطرف الأيمن كلّها تحمل القيمة Enabled كما يظهر في الشكل التالي: عند هذه المرحلة أعد تشغيل الخادوم، وبهذا يصبح جاهزًا للعمل. الخلاصة تعلّمنا في هذا الدرس كيفيّة تنصيب برنامج SQL Server 2012 وضبط الإعدادات اللازمة لكي يعمل بالصورة الصحيحة لتخديم شير بوينت بالشكل المناسب. سنتابع العمل من خلال هذه السلسلة بحيث نبدأ في الدرس التالي بتجهيز خادوم التطبيقات والويب. حيث سنبدأ فعليًّا بتنصيب شير بوينت وتجهيزه للعمل وللاستثمار.
  8. هل الحقلين Help.RequestCat_id و Help.OfferCat_id هما حقلين Foreign Key؟ إذا كانا كذلك فيمكن أن تستخدم استعلام SELECT مع INNER JOIN على الشكل التالي مثلًا: SELECT Help.ID[help_id], Help.Details[help_details], Help.DateTime[help_datetime], c1.Name, c2.Name FROM Help INNER JOIN Categories c1 ON Help.OfferCat_id = c1.ID INNER JOIN Categories c2 ON Help.RequestCat_id = c2.ID لقد اختصرت استعلامك السابق بغرض التبسيط. حاول تجربة هذا الاستعلام، وفي حال نجاحه يمكنك إضافة جدول Users إليه.
  9. هل كان يعمل معك الموقع من قبل ثم فجأة توقف عن العمل. أم أنّ هذه المشكلة قد ظهرت من البداية؟
  10. هذا أمر غريب. ينبغي أن يظهر لك استخدام ما لأنّك استخدمت الموقع فعليًا. حسنًا، جرّب تسجيل حساب جديد في غوغل واطلب مفتاح جديد ثم جرّب هل ستبقى هذه المشكلة.
  11. يُعتبر مفهوم النوّاب من المفاهيم الأساسيّة في سي شارب، وستستخدمه بشكل أو بآخر في أيّ برنامج حقيقي مكتوب بهذه اللغة. سنتحدّث في هذا الدرس عن هذا الموضوع المهمّ، وسنتعرّض في درس لاحق إلى مفهوم مهم آخر مرتبط به، ألا وهو مفهوم الأحداث Events. في جميع البرامج التي صادفناها في هذه السلسلة كنّا نعمل على استدعاء توابع وخصائص من كائنات ننشئها من الأصناف المختلفة. في البرمجة العمليّة، يحتاج الكائن في الكثير من الأحيان إلى وسيلة يفعل فيها العكس. أي يحتاج الكائن إلى أسلوب يستطيع من خلاله استدعاء تابع ما لا ينتمي إليه وذلك من تابع أو خاصيّة موجودة داخل الكائن. تُسمّى هذه الظاهرة بالردود callbacks، وهي تقنيّة مهمّة جدًّا مستخدمة حتى في أنظمة التشغيل على نحو واسع. ربما قد تتساءل لماذا يحتاج الكائن لأن يستخدم مثل هذه التقنيّة (الردود). الجواب على ذلك بسيط، فقد يحتاج الكائن إلى التعبير عن حالته الداخليّة، أو عن أمر طارئ قد حدث له، ففي تطبيقات سطح المكتب desktop applications مثلًا، يُعتبر أيّ زر موجود على نافذة البرنامج عبارة عن كائن. فعندما ينقر مستخدم البرنامج هذا الزر، فمن الطبيعي أن يبلّغنا الزر عن "حدث" النقر عليه. فكيف يفعل ذلك؟ يفعل ذلك ببساطة عن الطريق الردود التي نسمّيها في سي شارب بالنوّاب (ستعرف سبب التسمية بعد قليل). التصريح عن نائب يمكنك اعتبار النائب كصنف مستقل بحد ذاته، مع أنّ التصريح عنه يختلف عن التصريح عن الأصناف. تُصرّح الشيفرة التالية عن النائب SumDelegate: public delegate int SumDelegate(int a, int b); النوّاب -وعلى سبيل التبسيط- عبارة عن مغلّفات للتوابع. فالنائب SumDelegate السابق يمكنه أن يغلّف أو يشير إلى أيّ تابع آخر بشرط أن يقبل وسيطين من نوع int ويُرجع قيمة من نوع int أيضًا (لاحظ الشيفرة السابقة). فإذا أزلنا الكلمة المحجوزة delegate من الشيفرة السابقة، سيبدو الأمر "كما لو أنّنا" نصرّح عن التابع SumDelegate الذي يقبل وسيطين من النوع int ويُرجع قيمة من النوع int، وهو بمحدّد وصول public. لفهم الموضوع بشكل أفضل دعنا نستخدم النائب السابق في البرنامج Lesson13_01: 1 using System; 2 3 namespace Lesson13_01 4 { 5 public delegate int SumDelegate(int a, int b); 6 7 class Program 8 { 9 static void Main(string[] args) 10 { 11 SumDelegate handler = new SumDelegate(Sum); 12 13 int result = handler(5, 6); 14 15 Console.WriteLine(result); 16 } 17 18 static int Sum(int a, int b) 19 { 20 return a + b; 21 } 22 } 23 } لاحظ أولًا أنّنا وضعنا التصريح عن النائب SumDelegate في السطر 5 خارج أي صنف، مع أنّه كان ممكنًا أن نصرّح عنه ضمن الصنف Program. صرّحنا في الأسطر من 18 إلى 21 عن تابع ساكن static ضمن الصنف Program اسمه Sum يقبل وسيطين من النوع int ويُرجع قيمة من النوع int أيضًا. العمليّة التي يقوم بها هذا التابع بسيطة، فهو يجمع قيمتي الوسيطين الممرّرين إليه ويُرجع الناتج بسطرٍ واحد. انظر الآن إلى السطر 11 ضمن التابع Main. ستلاحظ أنّنا نصرّح عن المتغيّر handler من النوع (النائب) SumDelegate، ونُسند إليه كائنًا من نفس النوع باستخدام التعبير (new SumDelegate(Sum حيث مرّرنا إلى بانيته الوسيط Sum. ولكن أليس الوسيط Sum هو نفسه اسم التابع الساكن المصرّح عنه ضمن الصنف Main! في الواقع تتطلّب بانية النائب SumDelegate (على اعتباره صنفًا) وسيطًا عبارة عن تابع يقبل وسيطين من النوع int ويرُجع قيمة من النوع int، أي بشكل مماثل لتصريح النائب SumDelegate في السطر 5. انظر إلى العبارة البرمجيّة التالية في السطر 13: int result = handler(5, 6); أصبح بإمكاننا الآن أن نستدعي النائب handler بوسيطين من النوع int، وسيُرجع بالتأكيد قيمة من النوع int أيضًا. إذًا أصبح handler "ينوب" عن التابع Sum في عمليّة الاستدعاء، رغم أنّه في حقيقة الأمر سيستدعي التابع Sum ولكن من وراء الكواليس! يمكن باستخدام هذه التقنيّة وبإجراء بعض التعديلات الطفيفة (كما سنرى في الأحداث Events)، أن ينوب handler عن أكثر من تابع بنفس الوقت بشرط أن يقبل كلّ منها وسيطين من نوع int ويُرجع كلّ منها قيمة من النوع int. استخدام النواب بشكل عملي لنتناول برنامجًا يوضّح استخدام النوّاب بشكل عمليّ أكثر. انظر البرنامج Lesson13_02: 1 using System; 2 3 namespace Lesson13_02 4 { 5 public class Car 6 { 7 public delegate void SpeedNotificatoinDelegate(string message); 8 9 private SpeedNotificatoinDelegate speedNotificationHandler; 10 11 public void RegisterWithSpeedNotification(SpeedNotificatoinDelegate handler) 12 { 13 this.speedNotificationHandler = handler; 14 } 15 16 public int CurrentSpeed { get; set; } 17 public int MaxSpeed { get; set; } 18 19 public Car() 20 { 21 CurrentSpeed = 0; 22 MaxSpeed = 100; 23 } 24 25 public Car(int maxSpeed, int currentSpeed) 26 { 27 CurrentSpeed = currentSpeed; 28 MaxSpeed = maxSpeed; 29 } 30 31 public void Accelerate(int delta) 32 { 33 CurrentSpeed += delta; 34 35 if (CurrentSpeed > MaxSpeed) 36 { 37 if(this.speedNotificationHandler != null) 38 { 39 string msg = string.Format("You exceed the maximum speed! (Current = {0}, Max = {1})", 40 CurrentSpeed, MaxSpeed); 41 42 speedNotificationHandler(msg); 43 } 44 } 45 } 46 } 47 48 class Program 49 { 50 static void Main(string[] args) 51 { 52 Car car = new Car(100, 0); 53 54 car.RegisterWithSpeedNotification(new Car.SpeedNotificatoinDelegate(OnExceedMaxSpeedHandler)); 55 56 for(int i = 0; i < 5; i++) 57 { 58 Console.WriteLine("Increasing speed by 30"); 59 car.Accelerate(30); 60 } 61 } 62 63 static void OnExceedMaxSpeedHandler(string message) 64 { 65 Console.WriteLine(message); 66 } 67 } 68 } نفّذ هذا البرنامج لتحصل في الخرج على ما يلي: Increasing speed by 30 Increasing speed by 30 Increasing speed by 30 Increasing speed by 30 You exceed the maximum speed! (Current = 120, Max = 100) Increasing speed by 30 You exceed the maximum speed! (Current = 150, Max = 100) خذ نفسًا عميقًا، وجهّز كوبًا من الشاي (شرابي المفضّل) لندخل في تفاصيل البرنامج. ينقسم هذا البرنامج إلى صنفين: الصنف Car (من السطر 5 حتى السطر 46) والصنف Program (من السطر 48 حتى السطر 67). يمثّل الصنف Car القالب العام لسيّارة، ويحتوي على خاصيّتين CurrentSpeed و MaxSpeed وتعبّران عن السرعة الحالية والسرعة القصوى على الترتيب. كما يحتوي على بانيتين، إحداهما عديمة الوسائط، والثانية ذات وسيطين من نوع int لسهولة الإنشاء والإسناد للخصائص. يضم الصنف Car أيضًا النائب SpeedNotificatoinDelegate (السطر 7). تذكّر أنّه من الممكن أن تكون النوّاب ضمن الأصناف. يمكن لهذا النائب أن يغلّف أي تابع يقبل وسيطًا واحدًا من النوع string ولا يرجع أي قيمة (void). نعرّف أيضًا ضمن الصنف Car الحقل speedNotificationHandler (السطر 9) من النوع SpeedNotificatoinDelegate وذو محدّد وصول private، وأخيرًا يحتوي الصنف Car على التابعين Accelerate الذي يعبّر عن إكساب السيّارة المزيد من السرعة، وهو يتطلّب وسيطًا واحدًا من النوع int ويمثّل مقدار الزيادة في السرعة. والتابع RegisterWithSpeedNotification الذي يتطلّب وسيطًا واحدًا من النوع SpeedNotificatoinDelegate. وظيفة هذا التابع هو استقبال وسيط من النوع (النائب) SpeedNotificatoinDelegate وإسناده إلى الحقل الخاص speedNotificationHandler. سيغلّف النائب الممرّر لهذا التابع تابعًا آخر يقبل وسيطًا واحدًا من النوع string ولا يُرجع أي قيمة (void). يحتوي الصنف Program على تابعين: الأوّل هو Main (من السطر 50 حتى السطر 61) وهو غنيّ عن التعريف. والثاني هو OnExceedMaxSpeedHandler (من السطر 63 حتى السطر 66) الذي يحتاج إلى وسيط نصي واحد، ولا يرجع شيء (void)، وهو يحتوي على عبارة برمجيّة وحيدة وظيفتها عرض قيمة الوسيط النصيّ msg على الشّاشة. يبدأ البرنامج في التابع Main بالتصريح عن المتغيّر car وإسناد كائن جديد إليه من النوع Car، حيث نمرّر 100 كسرعة قصوى، والقيمة 0 كسرعة حاليّة إلى بانية الصنف Car. بعد ذلك سيعمل البرنامج على إنشاء كائن نائب يغلّف التابع OnExceedMaxSpeedHandler من خلال التعبير: new Car.SpeedNotificatoinDelegate(OnExceedMaxSpeedHandler) سيمرَّر هذا الكائن الجديد إلى التابع RegisterWithSpeedNotification كما هو واضح من السطر 54. يدخل البرنامج بعد ذلك في حلقة for (الأسطر من 56 حتى 60) التي ستتكرّر 5 مرّات، وبعد أن يتم استدعاء التابع Accelerate أربعة مرّات (السطر 59)، تصبح عندها السرعة الحالية تساوي 120 وهي أكبر من السرعة القصوى، لذلك يُستدعى التابع الذي يغلّفه النائب speedNotificationHandler (السطر 42) بالشكل: speedNotificationHandler(msg); والذي هو في حالتنا التابع OnExceedMaxSpeedHandler ليمرّر إليه رسالة نصيّة ضمن المتغيّر msg توضّح بأنّه قد تمّ تجاوز السرعة القصوى المحدّدة. وستتكرّر نفس العمليّة من أجل الدورة الخامسة والأخيرة للحلقة for. لاحظ الاختبار الذي أجريناه في السطر 37 من التابع Accelerate. يتأكّد هذا السطر من أنّ الحقل speedNotificationHandler ليس فارغًا (يحوي null). لأنّه إذا كان يحوي null فلا ينبغي تنفيذ عبارة الاستدعاء في السطر 42. أنصح بأن تستخدم تطبيق Visual Studio من أجل هذا البرنامج، حيث يمكن أن تستفيد من المنقّح Debugger الخاص به لتنفيذ البرنامج خطوة بخطوة (استخدم المفتاح F11 لتنفيذ البرنامج بشكل خُطَويّ) لفهم أفضل له. ملاحظة: أيّ حقل مصرّح عنه ضمن صنف ما ويكون من نوع مرجعيّ reference type تكون القيمة الافتراضيّة له هي null في حال لم نُسند إليه أي قيمة عند التصريح عنه. وتعني null أنّ هذا الحقل لا يحتوي على مرجع لأيّ كائن. ويسري نفس الأمر على المتغيّرات المحليّة التي نصرّح عنها ضمن التوابع والتي تكون أيضًا من أنواع مرجعيّة. ملاحظة: يمكن لأي نائب أن يغلّف توابع عاديّة أو توابع ساكنة static. تمارين داعمة تمرين 1 أجرِ تعديلًا على البرنامج Lesson13_02 بحيث يستخدم البرنامج النائب speedNotificationHandler لإرسال تنبيه إلى التابع الذي يُغلّفه هذا النائب، في حال وصلت السرعة الحالية إلى منتصف السرعة القصوى أو تجاوزتها (التنبيه يجب أن يصدر لمرّة واحدة). (تلميح: ستحتاج إلى التصريح عن حقل خاص ضمن الصنف Car من نوع bool مثلًا لكي يعرف البرنامج أنّه قد أصدر التنبيه الخاص بالوصول إلى منتصف السرعة القصوى، لكيلا يعيد إصدار مثل هذا التنبيه مرّة أخرى). تمرين 2 أجرِ تعديلًا آخرًا على البرنامج Lesson13_02 بحيث تستغني فيه عن استخدام التابع RegisterWithSpeedNotification. دون التغيير في أسلوب عمل البرنامج. (تلميح: ستحتاج إلى جعل الحقل speedNotificationHandler ذو محدّد وصول public بدلًا من private، ثم تتعامل مع هذا الحقل مباشرةً من الصنف Main). الخلاصة تعرّفنا في هذا الدرس على مفهوم جديد لكنّه أساسيّ وهو النوّاب Delegates. حيث اكتشفنا كيف أنّ النوّاب هي وسائل لتحقيق مبدأ الردود callbacks المهم في عالم البرمجة، والمستخدم على نطاق واسع في أنظمة التشغيل في تبادل الرسائل بين الكائنات المختلفة. تعلّمنا كيف يُغلّف النائب تابعًا يوافق معايير معيّنة تكون محدّدة عند التصريح عن النائب. في الحقيقة تُعتبر النوّاب الركن الأساسيّ للأحداث Events، ذلك المفهوم المهم في البرمجة كائنيّة التوجّه، والذي سنتحدّث عنه في الدرس التالي.
  12. حسبما يظهر من الصور المرفقة، فهناك مشكلة في مفتاح API التي أعطته إيّاك غوغل. والسؤال هنا، هل كان موقعك يعمل منذ فترة ثم توقّف عن العمل فجأة؟ إذا كان الأمر كذلك، وكان مفتاح API الذي تستخدمه مجاني، فهناك حدود للإستهلاك يبدو أنّك قد وصلت إليها لذلك توقّف غوغل عن الاستجابة. يمكنك مراجعة المزيد عن هذا الموضوع من هنا، حيث يتحدّث عن أنواع الاستيثاق الذي تستخدمه غوغل للوصول إلى خدمة خرائطها.
  13. بعد تجهيز خادوم المتحكّم بالمجال Domain Controller في الدرسين السابقين، سنعمل في هذا الدرس على تجهيز خادوم قاعدة البيانات ثمّ نضمّه إلى المجال hsoub-sp.com الذي أنشأناه مسبقًا. سننصّب أولًا نسخة Windows Server 2012 R2 كما فعلنا في درس سابق من هذه السلسلة. ثمّ سنعمل على تنصيب SQL Server 2012 على هذا الخادوم في الدرس التالي. تتعلّق المواصفات التي ينبغي أن يتمتّع بها هذا الخادوم بحجم العمل للشركة التي ننصّب مزرعة شير بوينت لها. تنصح مايكروسوفت في حال كان عدد المستخدمين أقل من 1000 مستخدم، أن يكون المعالج رباعيًّا (بصرف النظر عن نوعه)، وألّا يقلّ حجم الذاكرة RAM عن 8 جيجا بايت. في الحقيقة يمكنك تشغيل خادوم قاعدة البيانات بمواصفات أقل، ثمّ يمكنك الترقية إلى المواصفات الأعلى إذا تطلّب الأمر ذلك. تنصيب نظام التشغيل وتغيير اسم الخادوم وعنوانه نصّب نظام التشغيل Windows Server 2012 R2 كما هو موضّح في هذا الدرس ولا تنس إجراء التحديث له. بعد الانتهاء انقر زر ابدأ لتصل إلى صفحة البداية، ثم انقر بزر الفأرة الأيمن على اللوح This PC (إذا لم يكن موجودًا فيمكنك البحث عنه بكتابة This PC مباشرةً وأنت ضمن صفحة البداية) ثم اختر Properties من القائمة. بعد أن تظهر نافذة الخصائص لهذا الخادوم انقر زر Change Settings (الموجود في الجهة اليمنى) لتظهر نافذة أخرى انقر منها الزر Change كما مرّ معنا سابقًا في هذه السلسلة. ستظهر النافذة التالية، غيّر اسم هذا الخادوم ضمن الحقل Computer name ليصبح HSB-DB: بعد نقر زر موافق ليعيد ويندوز تشغيل هذا الخادوم. بعد الانتهاء من إعادة التشغيل وتسجيل الدخول مجدّدًا إلى ويندوز، انقر زر ابدأ لتصل إلى صفحة البداية واكتب مباشرةً Network and Sharing Center. بعد الحصول على النتيجة المطلوبة انقر عليها لتظهر لنا نافذة مركز الشبكة والمشاركة Network and Sharing Center. انقر على الاتصال المناسب من الجهة اليمنى. بالنسبة إليّ، لديّ اتصال وحيد اسمه Ethernet0. ستظهر نافذة الحالة لهذا الاتصال انقر منها الزر Properties لتظهر نافذة جديدة تمثّل خصائص الاتصال Ethernet0، اختر من القائمة التي تظهر أمامك البروتوكول Internet Protocol Version 4 (TCP/IPv4) ثم انقر زر Properties من الأسفل. سأختار العنوان 192.168.25.1 لهذا الخادوم كما في الشكل التالي: لاحظ هنا أنّني قد وضعت العنوان 192.168.25.10 ضمن خانة عنوان Preferred DNS Server وهو عنوان خادوم المتحكّم بالمجال الذي يمتلك ميزة خادوم DNS أيضًا كما تذكر. انقر زر موافق OK لتنتهي هذه المرحلة. ضمّ الخادوم إلى المجال hsoub-sp.com سنعمل الآن على ضمّ هذا الخادوم إلى المجال hsoub-sp.com. انقر زر ابدأ، ثم انقر بزر الفأرة الأيمن على اللوح This PC واختر Properties من القائمة. بخطوات مماثلة لما فعلناه قبل قليل عندما أردنا تغيير اسم الخادوم، انقر Change Settings ثم انقر Change من النافذة التي ستظهر. سنصل إلى النافذة التالية: لاحظ كيف اخترت Domain وكتبت اسم المجال الخاص بنا hsoub-sp.com. انقر زر OK ليطلب منك الويندوز تزويده باسم مدير المجال وبكلمة مروره: اكتب اسم مدير المجال الذي أنشأناه في الدرس السابق وهو SPAdmin بالإضافة إلى كلمة المرور، ولاحظ كيف يظهر اسم مجالنا أسفل مربع كلمة المرور من الشكل السابق. انقر موافق OK، إذا جرى كلّ شيء على ما يرام عندها ستحصل على رسالة الترحيب التالية التي تخبرك بنجاح عمليّة ضم خادوم قاعدة البيانات إلى المجال hsoub-sp.com: انقر الزر موافق OK ليطلب منك ويندوز إعادة تشغيل الخادوم، اقبل ذلك بالطبع. ملاحظة قد تفشل عمليّة إضافة خادوم إلى مجال ما في بعض الأحيان. وقد يعود ذلك إلى العديد من الأسباب والعوامل. على كلّ الأحوال إذا صادفتك مثل هذه المشكلة ولم تتمكّن من ضمّ هذ الخادوم أو غيره إلى المجال hsoub-sp.com فتأكّد أولًا أنّ خادوم المتحكّم بالمجال Domain Controller قيد التشغيل، وأنّه موصول إلى الشبكة وبإمكانك الاستعلام عنه من خادوم قاعدة البيانات باستخدام الأمر ping على الشكل التالي: افتح نافذة موجّه الأوامر ثم اكتب الأمر التالي: ping 192.168.25.10 يجب أن تحصل على إجابة من خادوم المتحكّم بالمجال بعد تنفيذ هذا الأمر، وإلّا فمن الممكن أن تكون هناك مشكلة في الشبكة، أو أنّك لم تضبط عنوان IP لخادوم قاعدة البيانات بشكل صحيح. على كلّ الأحوال يمكنك التواصل من خلال التعليقات المتاحة لهذا المقال في حال وجود أيّ مشكلة استعصى عليك حلّها. بعد إعادة التشغيل، وعند الوصول إلى نافذة تسجيل الدخول ستلاحظ أنّ ويندوز يحاول تسجيل الدخول باستخدام مدير النظام Administrator على نفس الخادوم HSB-DB من خلال الصيغة: HSB-DB\Administrator ولا توجد مشكلة في ذلك. لكننا نريد تسجيل الدخول على المجال hsoub-sp.com وليس على الخادوم الحالي. لذلك انقر السهم الموجود في الأعلى في الجهة اليسرى، والذي يشير نحو اليسار. ستظهر لك نافذة جديدة تعرض المستخدمين الذين يمكنهم تسجيل الدخول. اختر Other user لتظهر لك النافذة التالية: أدخل اسم مدير المجال SPAdmin وكلمة المرور (لاحظ العبارة Sign in to: HSOUB-SP تحت مربع كلمة المرور) ثم اضغط Enter. سيتمّ عندئذٍ تسجيل الدخول إلى المجال hsoub-sp.com. إضافة الحساب SPAdmin إلى مجموعة مدراء النظام على الخادوم الحالي ستلاحظ أنّ مدير الخادوم Server Manager سيعمل بشكل تلقائي (إن لم يعمل بشكل تلقائي يمكنك تشغيله، فاختصاره موجود بجوار زر ابدأ). انقر القائمة Tools من الأعلى، ثمّ اختر Computer Management لتظهر نافذة إدارة الحاسوب Computer Management كما في الشكل التالي: لاحظ أنّني قد اخترت من الشجرة التي تظهر في الطرف الأيسر المجموعات والمستخدمين المحليّين Local Users and Groups ومنها اخترت المجموعات Groups، لتظهر في الطرف الأيمن من هذه النافذة جميع المجموعات المتوفّرة على هذا الخادوم بشكل محليّ (وليس على المجال hsoub-sp.com). انقر نقرًا مزدوجًا على المجموعة Administrators التي تمثّل مجموعة مدراء النظام على هذا الخادوم لتظهر النافذة التالية: لاحظ وجود مجموعة مدراء المجال hsoub-sp ضمن المجموعة Administrators (المجموعة HSOUB-SP\Domain Admins). ولكّننا نحتاج إلى إضافة المستخدم SPAdmin بشكل صريح إلى المجموعة Administrators. لذلك انقر زر Add من الأسفل لتظهر لك نافذة جديدة. اكتب في المربّع Enter the object names to select الاسم SPAdmin ثم انقر الزر Check Names الموجود في الطرف الأيمن ليبحث عن هذا الاسم ويعرضه لك بشكله الكامل: انقر زر موافق لتتم عمليّة الإضافة. انظر كيف أضاف ويندوز الحساب SPAdmin إلى مجموعة Administrators: انقر موافق OK لتنتهي عمليّة الإضافة. ملاحظة أنصح بأن تعطّل التشغيل التلقائيّ لمدير الخادوم Server Manager. لفعل ذلك، انقر القائمة Manage من الأعلى، ثم اختر Server Manager Properties. ثم اختر من النافذة التي ستظهر صندوق الاختيار Do not start Server Manager automatically at logon وانقر موافق OK. الخلاصة تعلّمنا في هذا الدرس كيفيّة إنشاء وتجهيز خادوم قاعدة البيانات وتغيير اسمه وعنوان IP الخاص به، ومن ثمّ ضمّه إلى المجال الخاص بشركتنا الوهميّة hsoub-sp.com. كما تعلّمنا كيفيّة إضافة الحساب SPAdmin وهو حساب مدير المجال hsoub-sp.com إلى مجموعة مدراء النظام Administrator الخاصّة بخادوم قاعدة البيانات، وذلك ليمتلك الصلاحيّات المحليّة الكاملة لمدير النظام المحليّ على خادوم قاعدة البيانات HSB-DB. سنعمل في الدرس التالي على تنصيب Microsoft SQL Server 2012 على هذا الخادوم.
  14. تناولنا في الجزء الأوّل كيفيّة إعداد خادوم وتجهيزه بتغيير اسمه وضبط عنوان IP فريد له. سنتابع العمل الآن في هذا الدرس ونحوّل هذا الخادوم إلى متحكّم بالمجال Domain Controller. سنعمل أولًا على إنشاء المجال hsoub-sp.com وهو مجال افتراضي وغير حقيقي. يشير الحرفان sp في اسم المجال إلى SharePoint. كما سنُكسِب هذا المتحكّم ميّزة DNS Server تسمح للمستخدمين بالوصول إلى خادوم ويب الخاص بمزرعة شير بيونت عن طريق عنوان مقروء وليس مجرّد عنوان IP عادي. الترقية إلى خادوم متحكّم بالمجال شغّل برنامج مدير الخادوم Server Manager من صفحة البداية، حيث تجده في القسم الأيسر منها. أو يمكنك أن تلاحظ وجوده بسهولة بجوار زر إبدا مباشرةً: بعد أن تظهر نافذة برنامج مدير الخادوم، انقر على القائمة Manage في الأعلى واختر Add Roles and Features لإضافة مزايا جديدة إلى ويندوز. ستظهر النافذة التالية: تعطينا هذه النافذة بعض المعلومات حول طريقة الاستخدام. انقر زر Next لتنتقل إلى نافذة أخرى تسمح لنا باختيار نمط التنصيب Select installation type. سنترك الإعدادات الافتراضيّة كما هي، انقر Next لتظهر النافذة التي تحدّد الخادوم الذي نريد التنصيب عليه: يمكننا في الواقع اختيار خادوم آخر لإضافة المزايا المطلوبة إليه. في حالتنا هذه لا يوجد سوى خادومنا الحالي لذلك فانقر Next. ستظهر نافذة تحتوي على جميع الأدوار Roles المتاحة التي من الممكن يأخذها هذا الخادوم: اختر من هذه الأدوار ما يلي: Active Directory Domain Services DNS Server من الممكن أن تظهر نافذة عند اختيار أيّ من هذين الدورين السابقين، تخبرك بوجود مزايا متعلّقة بهما والتي من الضروري تنصيبها أيضًا. سنوافق بالتأكيد على هذا الأمر لذلك فانقر زر Add Features في حال ظهرت مثل هذه النافذة. انقر بعد ذلك زر Next لتظهر نافذة المزايا Features. لا نريد إجراء أي تغيير هنا لذلك فانقر Next. ستظهر بعد ذلك نافذة Active Directory Domain Services توضّح أنّنا بصدد تنصيب الدليل النشط Active Directory حيث يعطينا معلومات عن هذا الموضوع. انقر زر Next لتظهر نافذة أخرى وهي DNS Server توضّح أنّنا سنثبّت ميزة خادوم DNS أي أنّ خادومنا سيلعب دور متحكّم بالمجال وأيضًا خادوم DNS. يفيد خادوم DNS في السماح للمستخدمين بكتابة عناوين إنترنت مقروءة بدلًا من كتابة عناوين IP مجرّدة. انقر Next لتظهر النافذة الأخيرة التي تسبق عمليّة التنصيب: اختر صندوق الاختيار Restart the destination server automatically if required واختر Yes في حال ظهرت رسالة تأكيد. يسمح هذا الاختيار بإعادة تشغيل الخادوم بشكل تلقائيّ إذا تطلّب الأمر ذلك. انقر زر Install لتبدأ عمليّة التنصيب، ستتطلّب عمليّة التنصيب بعض الوقت. بعد أن تنتهي هذه العمليّة، أنصح بإعادة تشغيل الخادوم حتى ولو لم يطلب ويندوز ذلك. بعد إعادة تشغيل الخادوم وتسجيل الدخول إلى ويندوز، شغّل برنامج مدير الخادوم Server Manager من جديد. هذه المرّة ستلاحظ وجود إشارة تعجّب ضمن مثلث أصفر صغير، انقر فوقها لتظهر قائمة صغيرة كما في الشكل التالي: انقر فوق Promote this server to a domain controller لترقية هذا الخادوم وتحويله إلى متحكّم بالمجال. ستظهر بعد ذلك سلسلة من النوافذ المتتالية التي تعرض علينا خيارات متعلّقة بالمجال الذي نريد إنشائه. النافذة الأولى هي نافذة اختيار كيفيّة إنشاء المجال، والتي تتضمّن ثلاثة خيارات: الخيار الأوّل هو إضافة هذا الخادوم إلى مجال domain موجود مسبقًا. أمّا الخيار الثاني فهو إضافة مجال جديد إلى مجموعة خواديم موجودة مسبقًا. أمّا الخيار الأخير، فهو إنشاء مجال جديد لمجموعة من الخواديم (Add a new forest). اختر الخيار الأخير، ثمّ اكتب الاسم hsoub-sp.com لاسم المجال Root domain name كما يظهر في الشكل التالي تمامًا. ثمّ انقر بعد ذلك الزر Next. بعد ذلك ستظهر النافذة التالية، التي تسمح لنا بوضع كلمة مرور خاصّة بطور الاستعادة restore mode. اكتب كلمة المرور التي ترغبها ثم انقر Next. ملاحظة أفضّل أن تكون كلمات المرور التي ستستخدمها من أجل هذه السلسلة متطابقة، وذلك من أجل عدم نسيان أيّ منها. ولكن عندما تجهّز هذه المزرعة من أجل شركة فعليّة يتوجّب عليك بكل تأكيد استخدام كلمات مرور قويّة ومختلفة. إعداد خدمة DNS ستظهر بعد ذلك النافذة الخاصة بخيارات DNS والتي يظهر في أعلاها شريط تنبيه أصفر صغير، ولا بأس في ذلك لأنّنا نعمل على شبكة داخلية. لا نريد إجراء أي تغيير هنا لذلك انقر زر Next فحسب، لتحصل على نافذة الخيارات الإضافيّة والتي تضم اسم NetBIOS الخاص بهذا المجال لأغراض التوافقيّة: انقر زر Next لتظهر النافذة الخاصّة بتحديد المسارات، لا نريد أيضًا إجراء أي تغييرات هنا، لذلك انقر الزر Next دون إجراء أيّ تعديل. ستحصل على النافذة التالية التي تلخّص المهام التي سيعمل على تنفيذها برنامج الإعداد. انقر على الزر Next لتظهر النافذة الأخيرة التي تفحص متطلّبات التنصيب والتي ستعطيك تقريرًا في نهاية عملها حول إمكانيّة بدء عمليّة التنصيب. ستحصل على نافذة شبيهة بما يلي: يمكنك سحب شريط التمرير كما يظهر من الشكل أعلاه لتتأكّد أنّ الاختبارات قد نجحت تمامًا. لاحظ العلامة الخضراء الصغيرة التي تظهر بجوارها العبارة: All prerequisite checks passed successfully. Click 'Install' to begin installation. التحذيرات ذات اللون الأصفر ليست مهمّة حاليًا فهي تتعلّق بميّزة DNS وبموضوع التشفير والتوافقيّة مع الإصدارات القديمة ولن تؤثّر على عملنا مطلقًا. نحن مستعدّون الآن لبدء عمليّة التنصيب النهائيّة. انقر زر التنصيب Install. ستبدأ عمليّة التنصيب وتأخذ بعض الوقت، وعندما تنتهي سيتم إعادة تشغيل الخادوم بشكل تلقائيّ. بعد إعادة التشغيل والوصول إلى نافذة تسجيل الدخول ستلاحظ وجود بعض التغييرات. انظر إلى الشكل التالي: لاحظ كيف أصبح اسم مدير النظام Administrator مسبوقًا باسم المجال HSOUB-SP الذي أنشأناه قبل قليل، وهذه بالطبع إشارة جيّدة إلى نجاح العمليّة. أدخل كلمة المرور ثم سجّل الدخول. هذه المرّة ستسجّل الدخول إلى المجال HSOUB-SP. أنصحك عند هذه النقطة التحقّق من وجود تحديثات لويندوز، وتثبيتها أولًا قبل المتابعة. أصبح بذلك المجال hsoub-sp.com جاهزًا لإضافة باقي خواديم مزرعة شير بوينت إليه. إنشاء حساب مدير المجال hsoub-sp.com سنعمل الآن على إنشاء حساب مدير المجال ضمن الدليل النشط Active Directory. انقر زر ابدأ لتحصل على نافذة البداية. اكتب مباشرةً Active Directory Users and Computers لتحصل على النتيجة المطلوبة في قائمة نتائج البحث. انقر النتيجة التي ستحصل عليها لتظهر النافذة التالية: من الجهة اليسرى للنافذة، انشر محتويات اسم المجال hsoub-sp.com واختر المستخدمين Users، سيؤدّي ذلك إلى تحديث القسم الأيمن من هذه النافذة بجميع المستخدمين الموجودين افتراضيًّا ضمن المجال hsoub-sp.com. انقر بزر الفأرة الأيمن على المستخدم Administrator الموجود في أعلى القائمة، ثم اختر نسخ Copy لتظهر النافذة المسؤولة عن عمليّة النسخ كما في الشكل التالي: أدخل الاسم SPAdmin لكلّ من Full name و User logon name كما في الشكل السابق، ثم انقر Next لتصل إلى نافذة تطلب منك إدخال كلمة المرور وتأكيد لها لهذا المستخدم الجديد. أدخل كلمة مرور مناسبة، واحرص على أن تكون صناديق الاختيار كما في الشكل التالي: انقر زر Next لتحصل على نافذة تلخّص عمليّة النسخ، انقر زر Finish منها لتتم هذه العمليّة. تفيد عمليّة النسخ هذه في الحصول على جميع الصلاحيّات التي يتمتّع بها مدير المجال Administrator وإسنادها للمستخدم الجديد SPAdmin. الخلاصة تعلّمنا في هذا الدرس كيفيّة إنشاء متحكّم بالمجال Domain Controller بالإضافة إلى إنشاء مجال خاص بشركة وهمية hsoub-sp.com، كما أضفنا له ميّزة خادوم DNS. سنضمّ أيّ خادوم جديد نجهّزه إلى المجال السابق. لذلك يُعتبر هذا الدرس أساسيًّا لأنّ باقي دروس هذه السلسلة والتي تتحدّث عن ضم باقي أنواع الخودايم إلى مزرعة شير بوينت تعتمد عليه.
  15. تشبه البنية structure الصنف class إلى حدٍّ كبير باستثناء أنّها تُعتبر نوع قيمة value type وليس نوعًا مرجعيًّا كما هو الحال بالنسبة للأصناف. أمّا بالنسبة للمعدودة enum فهي تقنيّة تسمح لنا بتعيين مجموعة من الثوابت الرقميّة التي يمكن تسميّتها، وينحصر دورها في تنظيم البرنامج وجعل الشيفرة أكثر قابليّة للفهم والتعديل. البنى Structures تستطيع اعتبار البنية على أنّها نسخة مخفّفة من الصنف class. يكمن الفرق الأساسي بينهما في أنّ البنية هي نوع قيمة كما ذكرنا، فعند إنشاء بنية سيتم حجز المكان المخصّص لها في المكدّس stack وليس في الكومة heap كما هو الحال مع الأنواع المرجعيّة reference types. ستُنشئ الشيفرة التالية بنية اسمها Student على الشكل التالي: struct Student { public string FirstName { get; set; } public string LastName { get; set; } public int Mark { get; set; } public override string ToString() { return string.Format("{0} {1} ({2})",FirstName,LastName,Mark); } } لاحظ مدى الشبه بينها وبين الأصناف. الآن إذا أردنا استخدام هذه البنية في الشيفرة يمكننا ذلك من خلال العبارة التالية: Student student = new Student(); علينا أن نتذكّر دائمًا أنّ الكائن الذي يقوم العامل new بإنشائه سيكون في المكدّس stack. يمكننا أن نتابع ونستخدم المتغيّر student من نوع البنية Student كما كنّا نفعل من قبل مع متغيّرات الأصناف: student.FirstName = "Maher"; student.LastName = "Rajab"; student.Mark = 100; Console.WriteLine(student.ToString()); بعد تنفيذ الشيفرة السابقة ستحصل على الخرج: Maher Rajab (100) توجد الكثير من البنى المهمّة والمفيدة. فمثلًا هناك البنية DateTime التي تسمح لنا بالتعامل مع الزمن والتاريخ، وهي بنية مهمّة للغاية. انظر إلى البرنامج Lesson17_01 الذي يوضّح بعض المزايا التي توفّرها. 1 using System; 2 using System.Globalization; 3 4 namespace Lesson17_01 5 { 6 class Program 7 { 8 static void Main(string[] args) 9 { 10 DateTime myBirthDate = new DateTime(1979, 12, 25); 11 12 //display birth date in simple form: 13 Console.WriteLine(myBirthDate.ToString("dd/MM/yyyy")); 14 15 //display birth date in more elegent way: 16 Console.WriteLine(myBirthDate.ToString("D", CultureInfo.InvariantCulture)); 17 18 //add time info: 19 myBirthDate = myBirthDate.AddHours(4); 20 myBirthDate = myBirthDate.AddMinutes(30); 21 22 //display completed birth date info: 23 Console.WriteLine(myBirthDate.ToString("dddd, dd MMMM yyyy - hh:mm:ss tt", CultureInfo.InvariantCulture)); 24 } 25 } 26 } بعد تنفيذ البرنامج السابق ستحصل على الخرج التالي: أنشأنا في السطر 10 كائنًا جديدًا من البنية DateTime حيث مرّرنا ثلاثة وسائط للبانية هي على الترتيب من اليسار إلى اليمين: العام والشهر واليوم (الميلادي). في الحقيقة تمتلك بانية البنية DateTime اثنا عشرة شكلًا مختلفًا، نستطيع من خلال بعض هذه الأشكال ضبط الوقت أيضًا. يؤدّي الاستدعاء في السطر 13: myBirthDate.ToString("dd/MM/yyyy") إلى الحصول على تمثيل نصّي مختصر من التاريخ الذي مرّرناه إلى البانية قبل قليل. حيث ترمز dd إلى اليوم، و MM (حرف كبير) إلى الشهر، وyyyy إلى العام، ويمكنك بالتأكيد تغيير هذا الترتيب إذا أحببت (انظر إلى السطر الأوّل من الخرج في الشكل السابق). أمّا الاستدعاء في السطر 16: myBirthDate.ToString("D", CultureInfo.InvariantCulture) فيؤدّي إلى الحصول على نفس التاريخ ولكن بشكل أنيق. حيث سنحصل على القيم الكتابيّة للتاريخ (انظر السطر الثاني من الخرج في الشكل السابق). ولكن لاحظ أنّنا نمرّر إلى التابع ToString وسيطين: الأوّل هو النص التنسيقي "D" الذي يُخبر التابع ToString أنّنا نريد التنسيق على شكل تاريخ ولكن بصورة تفصيليّة أنيقة، أمّا الوسيط الثاني CultureInfo.InvariantCulture فهو يُرجع كائن من النوع CultureInfo. الهدف منه هو اعتماد الإعدادات الإقليميّة العالميّة في تنسيق التاريخ. وسبب ذلك أنّ كل بلد أو ثقافة culture لها أسلوب معيّن في تنسيق التاريخ (وكذلك الأمر بالنسبة للأرقام والعملات). لقد اخترت التنسيق العالميّ InvariantCulture لأنّني لا أريد من البرنامج استخدام الإعدادات الإقليميّة الخاصّة بنظام التشغيل في حاسوبي الشخصي الذي يعمل عليه البرنامج، لأنّ الخرج سيظهر مشوّهًا نتيجة لذلك. يكمن السبب في أنّ نافذة موجّه الأوامر console window لا تدعم اللغة العربية بشكل افتراضيّ، لذلك آثرت استخدام الإعدادات العالميّة (تشبه إلى حدٍّ كبير الإعدادات الخاصّة بالولايات المتحدّة). أخيرًا الاستدعاء في السطر 23: Console.WriteLine(myBirthDate.ToString("dddd, dd MMMM yyyy - hh:mm:ss tt", CultureInfo.InvariantCulture)); سيؤدّي هذا الاستدعاء إلى الحصول على النص الذي يظهر في السطر الثالث من الخرج، وهو مزيج بين التاريخ والوقت. لاحظ أنّنا قد أسبقنا هذا الاستدعاء باستدعاءين في السطرين 19 و20 للتابعين AddHours وAddMinutes على الترتيب. أتصوّر أنّ وظيفتهما واضحة، وهي إضافة قيمة ساعات ودقائق محدّدة إلى المتغيّر myBirthDate، مع الانتباه إلى أنّ كل منهما ستُرجع كائن DateTime جديد يمثّل التعديل الذي حصل. أي أنّ المتغيّر myBirthDate الأصلي لن يُمس في كلتا الحالتين. إلّا أنّنا أعدنا إسناد القيم المُعادة إلى المتغيّر myBirthDate لتجنّب إنشاء متغيّرات جديدة كما هو واضح من السطرين 19 و20. بقي أن أخبرك ما يلي: ترمز dddd إلى اليوم ولكن بصيغة كتابيّة. ترمز dd إلى اليوم ولكن بصيغة رقميّة. ترمز MMMM إلى الشهر ولكن بصيغة كتابيّة. ترمز yyyy إلى العام بصيغة رقميّة. ترمز hh إلى الساعات. ترمز mm (أحرف صغيرة) إلى الدقائق. ترمز ss إلى الثواني. ترمز tt إلى AM أو PM. ملاحظة هناك العديد من التوابع الأخرى التي لم نتناولها بالنسبة للبنية DateTime. كما أنّ هناك بنية أخرى اسمها TimeSpan متعلّقة بالبنية DateTime ويمكن من خلالها تمثيل فترة زمنيّة بدلًا من تاريخ محدّد. ملاحظة توجد خاصيّة ضمن البنية DateTime مفيدة كثيرًا وهي الخاصيّة Now. تُرجع هذه الخاصيّة التوقيت الحالي الذي يمثّل التاريخ والوقت الحاليين من ساعة الحاسوب. طريقة استخدامها بسيطة: DateTime current = DateTime.Now; المعدودات Enums المعدودة هي نوع قيمة value type خاص يسمح لنا بتعيين مجموعة من الثوابت الرقميّة ذات تسميّة. انظر مثلًا إلى تصريح المعدودة BorderSide التالي: public enum BorderSide { Left, Right, Top, Bottom } يمكن لهذا التصريح أن يوضع ضمن صنف ما، أو خارج أيّ صنف. عندها من الممكن استخدام هذه المعدودة بالشكل التالي: BorderSide topSide = BorderSide.Top; في الحقيقة إنّ لكلّ ثابت من ثوابت المعدودة (مثل Left أو Right أو غيرها) قيمة رقميّة ضمنيّة. تأخذ هذه الثوابت القيم الرقميّة الافتراضيّة 0، 1، 2، ... الخ بنفس الترتيب الذي تكون فيه هذه الثوابت ضمن تصريح المعدودة. فمثلًا في المعدودة BorderSide السابقة، يأخذ الثابت Left القيمة 0، والثابت Rigth القيمة 1، وهكذا. كما ويمكننا أيضًا أن نسند لثوابت المعدودة قيمًا رقميّة مباشرةً أثناء التصريح عنها. انظر إلى المعدودة BorderSide بشكلها المعدّل: public enum BorderSide { Left = 1, Right = 5, Top = 7, Bottom = 8 } أي ليس من الضروري أن تكون القيم الرقميّة متسلسلة أو تبدأ من الصفر. المهم فقط أن تكون صحيحة (بدون فاصلة عشريّة). يمكن الحصول على القيمة الرقميّة المُسندة إلى أيّ ثابت ضمن المعدودة بالشكل البسيط التالي: int i = (int)BorderSide.Left; بعد تنفيذ العبارة السابقة ستصبح قيمة المتغيّر i تساوي 1. تمارين داعمة تمرين 1 عرّف متغيّرين من البنية DateTime، سمّ الأوّل first وأسند إليه التاريخ 01/01/2016، وسمّ الثاني second وأسند إليه التاريخ 13/05/2016. وبعد ذلك نفّذ العبارة التالية وحاول تفسير الخرج: Console.WriteLine(second - first); تمرين 2 أنشئ برنامجًا يستخدم معدودةً اسمها LevelEnum تحتوي على الثوابت: Weak، Middle، Good، VeryGood. أضف هذه المعدودة إلى الصنف Student التالي: class Student { public string FirstName { get; set; } public string LastName { get; set; } public int Mark { get; set; } } ثمّ أضف لنفس الصنف السابق الخاصيّة Level من نوع المعدودة LevelEnum، حيث تُعبّر هذه الخاصيّة عن مستوى الطالب Student. الخلاصة تعرّفنا في هذا الدرس على البنى Structures والمعدودات Enums وكيفيّة استخدامهما. ستصادف في برامجك المستقبليّة هاتين التقنيّتين بشكل متكرّر. فإمّا أن تنشئهما بنفسك أو أن تفرض عليك أصناف دوت نت أو غيرها استخدامهما. تُعتبر البنى خفيفة، حيث أنّها سريعة في الإنشاء والمعالجة أكثر من الأصناف، كونها تتوضّح في مكدّس البرنامج كما أسلفنا. وتُعتبر المعدودات أداةً رائعة لتنظيم برامجك في حال كانت تتطلّب تعريف ثوابت عدديّة ضمن مجموعات منطقيّة.
  16. نعم الأفضل أن تقوم بذلك باستخدام SQL Server. بالنسبة لمنع أكثر من 3 رغبات، فستحتاج إلى القيام بذلك بشكل برمجي، ويكون ذلك على الشكل التالي: 1- قبل إضافة أي مُدخل (سجل) إلى الجدول StudentSchools والذي يمثّل رغبات الطلاب بالنسبة للمدراس، عليك أن تحصي عدد المدخلات الموجودة ضمن هذا الجدول لطالب محُدّد. 2- إذا كانت عدد المدخلات (الرغبات) لهذا الطالب أقل من 3 عندها فيمكنك إضافة مُدخل (رغبة) جديد. وإلّا فترفض تنفيذ هذه العمليّة. يمكنك إحصاء عدد المدخلات (الرغبات) الحالية لطالب محدد ضمن الجدول StudentSchools باستعلام SQL بسيط على الشكل التالي: SELECT COUNT(StudentId) FROM StudentSchools WHERE StudentId = @student_id حيث @student_id هو معرّف الطالب المراد البحث عنه
  17. بالرغم من أنّ المتحكّم بالمجال Domain Controller لا يُعتبر جزءًا من مزرعة شير بوينت SharePoint Farm إلّا أنّه يُعتبر ضروريًّا لتشغيل هذه المزرعة وإدارة الخواديم ضمنها، وإنشاء حسابات المستخدمين التي ستُستعمَل ضمن الشير بوينت وذلك من خلال الدليل النشط Active Directory. سنحتاج إلى خادوم فيزيائي ذي مواصفات عاديّة. سنفترض في هذه السلسلة أنّك تجهّز مزرعة شير بوينت لشركة صغيرة نسبيًّا لذلك فأيّ حاسوب ذي مواصفات عاديّة سيفي بالغرض. مع العلم أنّه يمكنك الانتقال إلى خادوم ذي مواصفات أعلى أو إضافة خادوم آخر إلى المزرعة في حال ازداد عدد المستخدمين ودعت الحاجة لذلك. سنعمل في البداية على تنصيب نظام التشغيل Windows Server 2012 R2 حيث يمكنك ذلك من خلال العودة إلى هذا المقال. ومن ثمّ سنعمل على ترقيّته ليصبح متحكّمًا بالمجال وإكسابه ميّزة DNS. تغيير اسم الخادوم سنبدأ بتغيير اسم الخادوم. انقر زر ابدأ Start لتظهر صفحة البداية، انقر بزر الفأرة الأيمن على اللوح This PC واختر Properties لتظهر لك النافذة التالية: انقر تغيير الإعدادات Change settings من الجهة اليمنى كما يظهر من الشكل السابق. ستظهر نافذة الإعدادات التالية: لاحظ الاسم الحالي WIN-9J5MA5JO0PO بالنسبة إلى حاسوبي (من الممكن أن يختلف الاسم الذي سيظهر عندك) والذي يظهر بعد Full computer name. هذا الاسم الافتراضي الذي يختاره برنامج الإعداد لويندوز عند تنصيبه. لنغيّر هذا الاسم إلى اسم معبّر يوضّح الغرض من هذا الخادوم. انقر الزر Change. لتظهر النافذة الخاصّة بتغيير اسم الخادوم: لقد اخترت الاسم HSB-DC وكتبته ضمن المربّع الخاص باسم الحاسوب Computer name. في الحقيقة يمكنك اختيار الاسم الذي ترغبه. يتألّف الاسم HSB-DC من قسمين: الأوّل هو HSB الذي يشير إلى حسّوب Hsoub والثاني هو DC الذي يشير إلى أنّ هذا الخادوم هو متحكّم بالمجال Domain Controller. يمكنك تقليد هذا النمط من التسمية إن أحببت. انقر بعد ذلك زر موافق OK. سيعرض عليك ويندوز إعادة تشغيل الخادوم. اقبل ذلك لننتقل إلى عمليّة ضبط عنوان IP له. ضبط عنوان IP للخادوم بعد إعادة تشغيل الخادوم، انقر زر ابدأ Start لتظهر صفحة البداية. ثم اكتب مباشرةً Network and Sharing Center ليعمل الويندوز على البحث عن هذه الجملة أثناء كتابتك لها. ستظهر في قائمة النتائج العبارة المطلوبة كما يظهر من الشكل التالي: بعد اختيار النتيجة السابقة ستظهر لك نافذة مركز الشبكة والمشاركة Network and Sharing Center: لديّ اتصال وحيد كما يظهر من ا windows server 2012لجهة اليمنى لهذه النافذة. اسم هذا الاتصال Ethernet0. من الممكن أن يظهر اسم مختلف لك. انقر هذا الاتصال للحصول على نافذة الحالة status له، ثمّ انقر زر الخصائص Properties الموجود في الأسفل لكي نحصل على نافذة الخصائص: نريد ضبط عنوان IP الخاص ببروتوكول TCP/IPv4 وقد اخترته كما يظهر من الشكل السابق. انقر زر Properties. ستظهر النافذة الخاصّة بضبط عنوان IP لهذا البروتوكول: احرص على ضبط الإعدادات لديك لتصبح مطابقة للإعدادات الموجودة في الشكل السابق. لاحظ أنّني قد استخدمت العنوان 192.168.25.10 يمكنك اختيار أيّ عنوان ترغبه، ولكن أنصحك أن تتقيّد حاليًا بعناوين IP الموجودة في هذه السلسلة لكي تحافظ على التوافقيّة بين جميع الخواديم ضمن مزرعة شير بوينت. من الأفضل الآن أن تعيد تشغيل الخادوم. التحقّق من عنوان IP قبل استخدامه يتوجّب عليك التأكّد من كون أيّ عنوان IP ترغب باستخدامه غير مستخدم من قبل في الشبكة. يمكنك التأكّد من هذا الأمر بفتح نافذة موّجه الأوامر من خلال نقر زر ابدأ للوصول إلى صفحة البداية، ثمّ اكتب بشكل مباشر cmd ستحصل على النتيجة الأولى Command Prompt أي موجّه الأوامر، انقره لتفتح نافذة موجّه الأوامر ثم نفّذ الأمر: ping 192.168.25.6 افترضت في الأمر السابق أنّني اختبر وجود العنوان 192.168.25.6 فإذا حصلت على الخرج التالي Reply from 192.168.25.100 Destination host unreachable فهذا يعني أنّ العنوان 192.168.25.6 السابق غير مُستخدم. تجاهل العنوان 192.168.25.100 الذي يظهر في خرج الأمر، فهو عنوان الحاسوب الذي أنفّذ أمر ping من خلاله. المشكلة التي قد تحدث، أنّه في بعض الحالات من الممكن تنفيذ أمر ping مع عنوان IP معيّن، ثم يخبرنا الأمر ping أنّ هذا العنوان غير مستخدم، ويكون الواقع مغايرًا لذلك! السبب في هذه المشكلة إن حدثت هو أنّ الجدار الناري الملحق بويندوز الموجود في الخادوم المستهدف بالأمر ping قد يمنع الاستجابة على هذا الأمر من باب الحماية. يمكن تجاوز هذا الأمر بسهولة من خلال تعديل بعض الإعدادات الخاصّة بالجدار الناري المرفق بنسخة ويندوز الموجودة في الخادوم الذي نستعلم عن عنوان IP له، بحيث نضيف استثناءً لهذا الجدار الناري يسمح من خلاله لويندوز بالاستجابة للأمر ping. انقر الزر ابدأ Start لتحصل على نافذة البداية، ثمّ اكتب بشكل مباشر Firewall لتعمل خاصيّة الإكمال التلقائي وتحصل على نتائج البحث. ستحصل في النتيجة الأولى على Windows Firewall with Advanced Security كما في الشكل التالي: انقر هذه النتيجة لتشغيل البرنامج المسؤول عن ضبط إعدادات الجدار الناري المتقدّمة كما في الشكل التالي: من القائمة اليسرى اختر Inbound Rules لضبط القواعد الخاصّة بالطلبات الشبكيّة الواردة، سيتم تعديل القسم الأيمن للنافذة لعرض هذه القواعد تلقائيًّا. ابحث عن القاعدة: File and Printer Sharing (Echo Request – ICMPv4-In) ثم انقر عليها بزر الفأرة الأيمن، لتظهر قائمة سياق صغيرة اختر منها الأمر Enable Rule كما في الشكل التالي: سيؤدّي ذلك إلى تفعيل هذه القاعدة، وبالتالي سيعمل أمر ping مع هذا الخادوم. ملاحظة سأستخدم في هذه السلسلة النطاق 192.168.25.x من أجل جميع خواديم المزرعة التي سننشئها. حيث x هو عدد أنصح بضبطه بين العددين 1 و254. كما أنصح أن تستخدم العناوين بين 192.168.25.1 و192.168.25.10 لتكون خاصّة بعناوين IP لخواديم المزرعة. أمّا باقي العناوين فيمكن إسنادها لأجهزة الحاسوب التي ستستثمر هذه المزرعة. الخلاصة تعلّمنا في هذا المقال كيفيّة تغيير اسم خادوم المتحكّم بالمجال بالإضافة إلى تغيير عنوان IP له. في الحقيقة سنحتاج إلى هذا المقال لاحقًا في هذه السلسلة، لأنّ هذا ما سنفعله من أجل باقي خواديم مزرعة الشير بوينت، وأيضًا من أجل أيّ حاسوب آخر نريد تغيير اسمه وعنوان IP له. من الضروري عدم تشابه عناوين IP بين الأجهزة، ومن الضروري أيضًا عدم تشابه أسمائها. وإلّا سنحصل على مشاكل تعارض في الشبكة. لذلك أنصح باستخدام مستند بسيط (أو ربما ورقة وقلم) لتدوين اسم وعنوان IP كلّ خادوم (أو جهاز حاسوب عادي) موجود على هذه الشبكة، مع وصف بسيط له. بالإضافة إلى استخدام الأمر ping كما أسلفنا لاختبار وجود عنوان IP مُستًخدم من قبل.
  18. أولًا لا أنصح مطلقًا باستخدام Access لأنّها غير مصمّمة أبدًا لهذه الغاية، وستحصل عاجلًا أم آجلًا على الكثير من المشاكل. استخدم بدلًا منها قواعد بيانات SQL Server على العموم ستحتاج برأيي إلى ثلاث جداول: 1- جدول Students يحتوي على بيانات الطلاب ويضم ثلاثة حقول: StudentId معرّف الطالب (مفتاح رئيسي) Name اسم الطالب Degree الدرجة العلمية للطالب. 2- جدول Schools يحتوي على بيانات المدارس ويضم ثلاثة حقول: SchoolId معرّف المدرسة (مفتاح رئيسي) Name اسم المدرسة. MinDegree الدرجة الدنيا للقبول في المدرسة. 3- جدول StudentSchools وهو جدول الربط بين الطلاب والمدارس ويضم حقلين: StudentId معرف الطالب (مفتاح رئيسي) SchoolId معرّف المدرسة (مفتاح رئيسي) ومن الممكن إنشاء مفتاح ثانوي foreign key بين الجدول الثالث وبين كل من الجدولين الأوّل والثاني وفق StudentId و SchoolId على الترتيب. بالنسبة إلى أنّ كل طالب يمكن ان يكون له 3 رغبات فقط، فهذا أمر يتم إنجازه من خلال الشيفرة البرمجية.
  19. بالنسبة ل ICollection اتصور انها ستعمل. جرب ذلك. أما أنها ستعمل لمرة واحدة فهذا لم أفهمه! إذا كان لديك مشكلة محددة فأرجو توضيحها مع إرفاق الكود
  20. يمكنك ذلك بالطبع، لقد كتبت لك مثالًا بسيطًا يرشدك لهذا الأمر. أجريت الفرضيّات التالية عند كتابتي لهذا المثال: 1- الصنف Student يحتوي على خاصيتين Id و Name. 2- الصنف School يحتوي على خاصيتين أيضًا: Name و Students. حيث أنّ الخاصية Students من النوع IList<Student>. انظر إلى الشيفرة التالية: public class Student { public int Id { get; set; } public string Name { get; set; } } using System.Collections.Generic; public class School { public IList<Student> Students { get; set; } public string Name { get; set; } } أنشئ مشروعًا جديدًا من نوع ASP.NET MVC ، وأضف إليه الصنفين السابقين (كل صنف بملف مستقل) ضمن المجلد Models. ثم اذهب إلى المتحكم IndexController وعدّل الأكشن Index ليكون على الشكل التالي: public ActionResult Index(School school) { if (school.Students == null) { school.Students = new List<Student>(); } return View(school); } وإليك الآن ملف العرض Index.cshtml: @model ModelBinding.Models.School @{ ViewBag.Title = "Home Page"; } @if (Model.Students.Count() == 0) { using (Html.BeginForm()) { <div class="form-group"> <h3>School Name</h3> @Html.TextBoxFor(m => m.Name, new {@class = "form-control", autofocus = "autofocus"}) </div> <hr/> for (int i = 0; i < 3; i++) { <div class="form-group"> <h4>Student @(i + 1)</h4> <label>Id</label> @Html.Editor("Students[" + i + "].Id") <label>Name</label> @Html.Editor("Students[" + i + "].Name") </div> } <button type="submit" class="btn btn-primary">Save</button> } } else { <h1>@Model.Name</h1> foreach (var student in Model.Students) { <p>@student.Id, @student.Name</p> } @Html.ActionLink("Back", "Index"); } نفّذ البرنامج وانتقل إلى Home/Index من المتصفّح، سيعرض إليك حقولًا فارغة لتعبّئها (افترضت أنّ هنا 3 طلاب فقط سيتم تعبئة البيانات لهم)، وبعد نقر Save ستُرسل البيانات إلى الأكشن Index ليفهمها ويعرضها لك مرّة أخرى. يمكنك تنفيذ البرنامج بوضع التنقيح وتنفيذه خطوة بخطوة لتفهم ما يجري بالضبط.
  21. يمكن القراءة والكتابة من وإلى الملفات النصيّة في سي شارب بعدّة طرق. سنتناول أسلوبًا بسيطًا وذلك من خلال الصنفين StreamWriter و StreamReader. يسمح الصنف StreamWriter بالكتابة فقط، أمّا الصنف StreamReader فهو يسمح بالقراءة فقط. كما يمكن استخدام كلا الصنفين في نفس البرنامج. وكلّ منهما موجود ضمن نطاق الاسم System.IO. يرث الصنف StreamWriter من الصنف TextWriter في حين يرث الصنف StreamReader من الصنف TextReader. الكتابة إلى ملف نصي سنعمل في البرنامج Lesson12_01 على إنشاء الملف data.txt وكتابة بعض الأسطر ضمنه: 1 using System; 2 using System.IO; 3 4 namespace Lesson12_01 5 { 6 class Program 7 { 8 static void Main(string[] args) 9 { 10 string[] lines = { "First Line", "Second Line", "Third Line" }; 11 12 StreamWriter fileWriter = new StreamWriter("data.txt"); 13 14 foreach (string line in lines) 15 { 16 fileWriter.WriteLine(line); 17 } 18 19 fileWriter.Close(); 20 } 21 } 22 } صرّحنا في السطر 10 عن المصفوفة lines التي عناصرها نصوص، لاحظ أنّنا استخدمنا الطريقة المختصرة لإنشاء كائن مصفوفة وإسناد العناصر الموجودة ضمن الحاضنة {} إلى عناصره مباشرةً. نصرّح في السطر 12 عن المتغيّر fileWriter حيث نسند إليه كائن من الصنف StreamWriter. عند إنشاء هذا الكائن، مرّرنا اسم الملف "data.txt" إلى بانية الصنف StreamWriter. في الحقيقة تخضع هذه البانية إلى زيادة التحميل overloading، حيث تمتلك ثمانية أشكال مختلفة اخترنا أبسطها، وهو مسار واسم الملف المراد إنشاؤه. وبما أنّنا مرّرنا الاسم فقط دون المسار، فسيتم إنشاء هذا الملف في نفس المجلّد الموجود ضمنه الملف التنفيذي للبرنامج. بعد ذلك نستخدم التابع WriteLine من المتغيّر fileWriter لكتابة عناصر المصفوفة lines على أسطر منفصلة ضمن الملف data.txt. العبارة البرمجيّة في السطر 19 ضرورية لإغلاق الملف باستدعاء التابع Close وتحرير المصدر الذي يحجزه في نظام التشغيل. جرّب تنفيذ البرنامج، لن تحصل على شيء على الشاشة، ولكن إذا فتحت الملف data.txt (ستجده غالبًا ضمن bin\debug ضمن مجلّد المشروع) ستجد الأسطر الثلاثة موجودةً ضمنه. ملاحظة: يوجد شكل آخر لبانية الصنف StreamWriter يقبل بالإضافة إلى اسم الملف ومساره قيمة منطقيّة (من نوع bool) تُدعى append. إذا مرّرت true مكانها فسيعمل البرنامج إلى الإضافة إلى محتويات الملف data.txt، أمّا إذا مرّرت false فسيعمل على الكتابة عليه. أمّا إذا أهملت هذا الشكل تمامًا كما هو الحال في مثالنا فسيعمل البرنامج على الكتابة على الملف، أي استبدال محتوياته، في كلّ مرّة ننفّذ فيها البرنامج. في الحقيقة ليس هذا هو الاستخدام الأمثل للصنف StreamWriter والسبب في ذلك أنّ مصادر نظام التشغيل محدودة، حيث يؤدّي التعامل مع الملفات إلى حجز بعض من هذه المصادر، لذلك ينبغي تحرير هذه المصادر فورًا عندما تنتفي الحاجة إليها. قد يبدو أنّنا قد فعلنا ذلك باستخدام التابع Close وهذا صحيح تمامًا، ولكن ليس بالسرعة القصوى الممكنة! هناك أسلوب آخر يسمح بتحرير المصادر بشكل أكثر فعاليّة وسرعة باستخدام الكلمة المحجوزة using. سأعدّل البرنامج Lesson12_01 ليستخدم هذا الأسلوب الجديد. انظر البرنامج Lesson12_02 بعد التعديل: 1 using System; 2 using System.IO; 3 4 namespace Lesson12_02 5 { 6 class Program 7 { 8 static void Main(string[] args) 9 { 10 string[] lines = { "First Line", "Second Line", "Third Line" }; 11 12 using (StreamWriter fileWriter = new StreamWriter("data.txt")) 13 { 14 foreach (string line in lines) 15 { 16 fileWriter.WriteLine(line); 17 } 18 } 19 } 20 } 21 } لاحظ السطر 12 كيف وضعنا عبارة التصريح عن المتغيّر fileWriter والإسناد إليه ضمن عبارة using. في الواقع لن يكون المتغيّر fileWriter مرئيًّا خارج حاضنة using (من السطر 13 حتى السطر 18)، وبمجرّد وصول تنفيذ البرنامج إلى السطر 19 سيتم إغلاق الملف فورًا وتحرير المصدر الذي يحجزه. يظهر من البرنامج السابق أنّنا لم نعد نحتاج إلى استخدام التابع Close. القراءة من ملف نصي سنستخدم الصنف StreamReader لهذا الغرض. سيعمل البرنامج Lesson12_03 على قراءة محتويات الملف data.txt السابق وعرضها على الشاشة: 1 using System; 2 using System.IO; 3 4 namespace Lesson12_03 5 { 6 class Program 7 { 8 static void Main(string[] args) 9 { 10 using (StreamReader fileReader = new StreamReader("data.txt")) 11 { 12 while(!fileReader.EndOfStream) 13 { 14 string line = fileReader.ReadLine(); 15 Console.WriteLine(line); 16 } 17 } 18 } 19 } 20 } تخضع بانية الصنف StringReader أيضًا لزيادة التحميل، حيث تمتلك 11 شكلًا مختلفًا تسمح للمبرمج بالتحكّم الكامل بكيفيّة القراءة من الملف. أبسط هذه الأشكال هو الشكل الذي استخدمناه في البرنامج Lesson12_03 حيث سنمرّر لهذه البانية اسم الملف data.txt الذي أنشأناه في البرنامج Lesson12_02 السابق. استخدمنا في هذا البرنامج أيضًا العبارة using (من السطر 10 حتى السطر 17) لتحرير المصدر الذي يحجزه الملف عند الانتهاء من القراءة. ننشئ كائن من الصنف StreamReader ونسنده إلى المتغيّر fileReader ضمن عبارة using في السطر 10. ثمّ نستخدم حلقة while لقراءة محتويات الملف، وذلك لأنّنا من الناحية النظريّة لا نعلم بالتحديد كم سطرًا يحوي الملف. لاحظ شرط استمرار حلقة while حيث تُرجع الخاصيّة EndOfStream للمتغيّر fileReader القيمة true إذا وصلنا إلى نهاية الملف أثناء عمليّة القراءة، وإلّا فإنّها تُرجع false. إذًا، في حال لم نصل بعد إلى نهاية الملف ستُرجع الخاصيّة القيمة EndOfStream القيمة false وبسبب وجود عامل النفي المنطقي (!) قبل هذه الخاصيّة مباشرةً، ستكون القيمة النهائيّة لهذا التعبير هو true مما يسمح لحلقة while بالاستمرار. أمّا عند الوصول إلى نهاية الملف سيحدث العكس تماماً مما يجعل شرط استمرار الحلقة false وينتهي تنفيذ الحلقة. نقرأ في السطر 14 سطرًا من الملف data.txt ونسنده إلى المتغيّر النصي line في كل دورة، ثمّ نطبع محتويات هذا المتغيّر إلى الشاشة في السطر 15. استخدمنا في عمليّة قراءة سطر من الملف data.txt التابع ReadLine من المتغيّر fileReader الذي يعمل على قراءة سطر واحد في كلّ مرّة من الملف data.txt. تمارين داعمة تمرين 1 اكتب برنامجًا يطلب من المستخدم إدخال خمس جُمل، ثم يعمل على تخزين هذه الجُمل على اعتبار أنّ كل جملة يُدخلها المستخدم تمثّل سطرًا نصيًّا. تخزّن كل جملة مع رقم سطرها بحيث يفصل بينهما محرف الجدولة (\t). تمرين 2 استفد من الصنف Student التالي: class Student { public string Name { get; set; } public int Mark { get; set; } } في كتابة برنامج يطلب من المستخدم إدخال بيانات خمسة طلّاب (اسم الطالب Name، والدرجة Mark) مستخدمًا المجموعة العموميّة <List<Student في تخزين بيانات هؤلاء الطلّاب (ستحتاج إلى استخدام نطاق الاسم System.Collections.Generic في بداية البرنامج). بعد الانتهاء من الإدخال، يجب على البرنامج حفظ بيانات هؤلاء الطلّاب ضمن الملف students.txt على شكل جدول بسيط، بحيث تصبح محتويات الملف مشابهة للشكل التالي: Amjad 50 Mohammad 80 Mazen 90 Nour 88 Anwar 40 الخلاصة تعرّفنا في هذا الدرس على المبادئ الأساسيّة في التعامل مع الملفات النصيّة. حيث تعلّمنا كيفيّة القراءة من الملف النصيّ وكيفيّة الكتابة إليه. وتعلّمنا أساليب مهمّة عند فتح الملف للقراءة أو الكتابة تتمثّل في استخدام العبارة using لكي نحرّر المصدر الذي يحجزه الملف فور الانتهاء من التعامل معه.
  22. نتابع في هذا المقال سلسلة تنصيب وتجهيز شير بوينت للعمل. يُعتبر هذا المقال مهمًّا في هذه السلسلة، فهو المرجع الذي سنعود إليه في كلّ مرّة نحتاج فيها إلى تجهيز خادوم جديد وضمّه إلى مزرعة الخواديم الخاصّة بشير بوينت. يمكنك تنزيل Windows Server 2012 R2 من هذا الرابط الذي يتيح لك تجربته لمدة 180 يومًا. يتطلّب التنزيل تسجيل الدخول إلى حسابك في مايكروسوفت. هذا الحساب هو نفسه حساب بريدك الإلكتروني عند مايكروسوفت. بعد تسجيل الدخول ستلاحظ أنّ الموقع يوفّر لك خيارات متعدّدة للتنزيل. سنختار منها الخيار ISO الذي يسمح لنا بحرق burn هذه النسخة على قرص DVD وبالتالي استخدامها في عمليّة التنصيب. انقر بعد ذلك الزر Register to continue. أدخل المعلومات التي يحتاجها الموقع منك ثمّ انقر زر Continue الموجود في الأسفل لتبدأ عملية التنزيل Download. بعد انتهاء التنزيل، وحرق نسخة ويندوز الموجودة بصيغة ISO على قرص DVD يمكننا البدء بعمليّة التنصيب. أولًا: عمليّة التنصيب أدخل القرص Windows Server 2012 R2 ثمّ أعد تشغيل الحاسوب وتأكّد من أنّ الإقلاع سيكون من خلال قرص DVD، بعد الإقلاع وتشغيل برنامج الإعداد ستحصل على الشكل التالي: اترك الإعدادات الافتراضيّة كما هي، ثم انقر Next. سينتقل برنامج الإعداد إلى نافذة في وسطها زر يحوي النص Install، انقره لبدء عمليّة التنصيب. ستظهر بعد ذلك نافذة تخيّرك في نوع الإصدار الذي ترغب بتنصيبه على الخادوم Windows Server 2012 R2 Standard أو Windows Server 2012 R2 Datacenter: يُعتبر الإصدار Standard كافيًا تمامًا بالنسبة إلى عملنا، لذلك سنختاره. لاحظ وجود العبارة (Server with a GUI) ويعني ذلك أنّه سيتم تنصيب نظام التشغيل هذا مع واجهة مستخدم رسوميّة تشبه إلى حدٍّ كبير واجهات ويندوز المألوفة. من الممكن أحيانًا أن ترى بعض الخيارات الإضافية لهذه القائمة التي تقترح تنصيب الإصدار Standard ولكن بدون واجهة رسوميّة (Server without a GUI)، يعتبر هذا الخيار جيّدًا في توفير مصادر الخادوم وخصوصًا فيما يتعلّق بالذاكرة، ولكنّه مخصّص للمستخدمين المتقدّمين. انقر الزر Next لتظهر لك اتفاقيّة ترخيص المستخدم. اختر صندوق الاختيار للموافقة على بندود اتفاقيّة الترخيص، وانقر Next. سينتقل برنامج الإعداد بعد ذلك إلى نافذة تخيّرك بين الترقية Upgrade والتخصيص Custom: سنختار الخيار الثاني وهو التخصيص Custom الذي يسمح لنا بإنشاء نسخة جديدة تمامًا. بعد نقرك على الخيار الثاني Custom سينتقل برنامج الإعداد إلى النافذة المخصّصة لتحديد القرص الذي ستجري فيه عملية التنصيب. ستلاحظ من خلال النافذة السابقة أنّ القرص الصلب عندي حجمه 60 جيغا بايت وهو غير مخصّص بعد Drive 0 Unallocated Space. قد تستغرب هذا الحجم الصغير للقرص الصلب، وهو في الواقع كذلك. يكمن السبب في ذلك أنّني أستخدم VMware Workstation وهي آلة افتراضيّة أستخدمها لتنصيب Windows Server 2012 R2 بهدف الشرح. بالنسبة إليك ستستخدم خادومًا حقيقيًّا بالطبع إلّا إذا أردت التجريب فحسب. انقر الخيار New الذي سيسمح لك بتخصيص هذه المساحة حيث سيظهر أسفل الزر New مربّع نص يسمح لك بإدخال الحجم المراد تخصيصه بالميغا بايت وعلى اليمين زر Apply لتنفيذ العمليّة. سيظهر ضمن هذا المربع الحجم الأقصى للقرص الصلب هذا كونه غير مخصّص بالكامل، بالنسبة إليك تستطيع اختيار الحجم الذي يwindows server 2012ناسبك والذي ترغب بتخصيصه. انقر الزر Apply لبدء عمليّة التخصيص. قد تظهر رسالة من برنامج الإعداد تخبرك بأنّه قد يُنشئ محرّك أقراص محجوز لأغراض خاصّة بنظام التشغيل، انقر زر موافق OK ليظهر الشكل التالي: لاحظ كيف أنشأ برنامج الإعداد الجزء Partition 1 المحجوز لنظام التشغيل بحجم 350 ميغا بايت، في حين خصّص المساحة الباقية للجزء الذي ستجري عليه عمليّة تنصيب نظام التشغيل وهو الجزء Partition 2. انقر زر Next للانتقال إلى المرحلة التالية. ملاحظة في حال كان لديك نظام تشغيل قديم على القرص الذي ترغب بإجراء عمليّة التنصيب عليه وأردت استبداله، فيمكنك نقر Format بدلًا من New لتهيئة ذلك القرص. ستبدأ عمليّة الإعداد، وسيعمل برنامج الإعداد على تنفيذ عدّة عمليّات ضمنها مثل نسخ ملفات الويندوز إلى القرص الصلب، والعمل على تهيئتها، وتنصيب بعض المكوّنات الأساسيّة، وإجراء التحديثات. بعد الانتهاء من عمليّة الإعداد، سيعيد برنامج الإعداد تشغيل الخادوم، وبذلك نصل إلى نهاية هذه العمليّة. بعد إعادة التشغيل، ستظهر نافذة تطلب من المستخدم إدخال كلمة مرور (مع تأكيدها) لحساب مدير النظام Administrator. أرجو اختيار كلمة مرور معقّدة تحتوي على مزيج من الأحرف والأرقام والمحارف مثل (@، %، !) وعدم التهاون أبدًا في هذا الموضوع. بعد أن تفرغ من إدخال كلمة المرور وتنقر Finish ستنتقل إلى شاشة القفل التالية. اضغط المفاتيح Ctrl + Alt + Delete معًا، لتظهر شاشة تسجيل الدخول. تأكّد أنّ المستخدم الحالي هو مدير النظام Administrator ثمّ أدخل كلمة المرور واضغط Enter. سيعمل الويندوز على تسجيل الدخول للمرّة الأولى. ملاحظة قد تختلف خطوات التنصيب بشكل طفيف عمّا تشاهده هنا، وذلك بحسب النسخة المستخدمة، وبحسب الخادوم الذي تجري عليه عمليّة التنصيب. تذكّر أنّني أُجري عملية التنصيب على آلة افتراضيّة. بعد تسجيل الدخول، ستظهر نافذة أمامك بشكل افتراضيّ هي نافذة برنامج مدير الخادوم Server Manager. هذا البرنامج مهم، ومن خلاله نستطيع التحكّم بإعدادات الخادوم، كما يمكن أيضًا إدارة حزم البرمجيّات التي تأتي مع Windows Server 2012. لكنّنا لا نرغب أن يظهر دومًا كلّما سجّلنا الدخول إلى ويندوز. لذلك انتقل إلى القائمة Manage في الأعلى، ثم اختر Server Manager Properties من القائمة التي ستظهر، لتحصل على النافذة التالية: انقر على صندوق الاختيار Do not start Server Manager automatically at logon ثم انقر الزر موافق OK. انتهت هنا عمليّة التنصيب، لتبدأ عمليّة التحديث في الفقرة التالية. ثانيًا: عمليّة التحديث تُعتبر هذه العمليّة حيويّة جدًّا ومكمّلة لعمليّة التنصيب. وإذا أردت نصيحتي: لا تلمس الخادوم قبل إجراء التحديث لنظام تشغيله! انقر على زر البدء في الزاوية اليسرى السفلى لتظهر لك صفحة البداية. يظهر في الجانب الأيسر لوح tile اسمه Control Panel، انقره لتظهر لك نافذة لوحة التحكّم. اختر العنصر System and Security لتحصل على الشكل التالي: من العنصر Windows Update اختر Check for updates (ضمن المستطيل الأحمر الصغير). سيعمل الويندوز على البحث عن أيّ تحديثات متوفّرة (وعلى الغالب سيجدها). نصّب هذه التحديثات ليصبح الويندوز جاهزًا لأيّ تخصيص. ملاحظة احرص أن يكون الخادوم موصولًا بشبكة الانترنت قبل إجراء عمليّة التحديث. الخلاصة أصبح الخادوم جاهزًا للاستخدام ولتخصيصه بحيث يلعب الدور المطلوب منه في مزرعة الخواديم. خلال تقدّمنا في هذه السلسلة قد أطلب منك العودة إلى هذا المقال، واتّباع الخطوات الموجودة ضمنه لتنصيب نسخة جديدة من ويندوز في كلّ مرّة أردنا فيها تجهيز خادوم جديد. بالنسبة لهذه السلسلة سنعمل على تخصيص خواديم للمتحكّم بالمجال Domain Controller، ولخادوم التطبيق مع الواجهة، ولخادوم قواعد البيانات Database Server.
  23. يُعتبر التعامل مع النصوص من المواضيع المهمّة التي يحتاجها أيّ مبرمج. توفّر سي شارب أساليب متقدّمة للتعامل مع النصوص، سنتحدّث في هذا الدرس عن بعض هذه الأساليب. حيث سنتعلّم كيفيّة البحث عن نص محدّد ضمن نص آخر، واستبدال نص بآخر، واستخلاص جزء محدّد من نص، وضمّ النصوص. النص في سي شارب هو سلسلة من المحارف char الواقعة بين علامتي الاقتباس المزدوج " ". لقد تعاملنا في العديد من المرّات مع النصوص في الدروس السابقة، وتعلّمنا كيف أنّ النوع string هو الذي يمثّل أي نص في سي شارب. البحث والاستبدال ضمن نص البحث ضمن نص للمحارف في أيّ نص ترتيب رقمي يبدأ من الصفر ويسمى الدليل index. إذا أردنا أن نبحث عن نص محدّد ضمن نص آخر فيمكن ذلك باستخدام التابع IndexOf الذي نستدعيه من النص المراد البحث ضمنه، ونمرّر إليه النص المراد البحث عنه، فيُرجع دليل أوّل محرف للنص المطابق في حال وجوده وإلّا فيرجع 1-. كمثال على ذلك انظر الشيفرة التالية: string text = "My friend Mohammad is a developer, Mohammad likes C#."; int pos = text.IndexOf("Mohammad"); بعد تنفيذ الشيفرة السابقة سيحمل المتغيّر pos القيمة 10 والتي تمثّل دليل الحرف M ضمن النص text. ربما تكون قد لاحظت أنّ النص Mohammad موجود في النص text مرّتين، فأيّ دليل أعاد التابع IndexOf؟ تجري عملية البحث باستخدام التابع IndexOf حسب ترتيب إدخال المحارف في النص text، لذلك فأوّل كلمة Mohammad مطابقة يصادفها تُنهي عمليّة البحث. ففي مثالنا السابق حدثت المطابقة عند كلمة Mohammad الموجودة بعد "My friend". أمّا إذا استخدمنا كلمة غير موجودة فسنحصل على القيمة 1- كما أسلفنا. انظر الشيفرة التالية: string text = "My friend Mohammad is a developer, Mohammad likes C#."; int pos = text.IndexOf("Amjad"); سيحمل المتغيّر pos القيمة 1- لأنّ النص الذي نبحث عنه غير موجود في النص text. يخضع التابع IndexOf في الواقع لزيادة التحميل، حيث أنّ هناك 9 أشكال مختلفة له. تؤمّن هذه الأشكال المزيد من مزايا البحث، حيث يمكننا مثلًا البحث عن نص ضمن جزء محدّد من النص الموجود في text، أو ابتداءً من دليل محدّد حتى آخر النص، وهكذا. هناك تابع آخر يسمح لنا بأن نبحث بشكل معكوس، وهو التابع LastIndexOf لفهم عمله بشكل جيّد سأعيد كتابة الشيفرة السابقة ولكن باستخدام التابع LastIndexOf: string text = "My friend Mohammad is a developer, Mohammad likes C#."; int pos = text.LastIndexOf("Mohammad"); بعد التنفيذ سيحمل المتغيّر pos القيمة 35، وذلك لأنّ المطابقة حدثت هذه المرّة مع كلمة Mohammad الثانية (تأتي قبل كلمة likes). حيث تمثّل القيمة 35 دليل الحرف M لهذه الكلمة بالنسبة للنص text. ملاحظة يمكنك أن تستخدم التابع ToUpper من أي متغيّر نصي والذي يعيد حالة الأحرف الطباعية الكبيرة للنص الموجود ضمن المتغيّر النصي دون أن يؤثّر ذلك على محتوى النص الأساسي ضمن المتغيّر. ونفس الأمر ينطبق على التابع ToLower والذي يعيد الحالة الطباعية الصغيرة. يفيد كل من التابعين السابقين أحيانًا في البحث إذا أردنا عدم التمييز بين الأحرف الطباعية الكبيرة والصغيرة عند عملية المطابقة بين الكلمات. انظر لكيفيّة استخدام هذين التابعين: string text = "Hello!"; string upper = text.ToUpper(); //upper will contains "HELLO!" string lower = text.ToLower(); //lower will contains "hello!" مع الانتباه إلى أنّ قيمة المتغيّر text تبقى كما هي. الاستبدال ضمن نص بالنسبة للاستبدال فالأمر يسير أيضًا، حيث يمكن استخدام التابع Replace لهذا الغرض. يُستدعى هذا التابع من النص الذي نريد إجراء عمليّة الاستبدال ضمنه، حيث يتطلّب هذا التابع وسيطين: الأوّل oldValue والذي يمثّل القيمة النصيّة المراد استبدالها، والوسيط الثاني newValue الذي يمثّل القيمة النصيّة الجديدة. يُرجع هذا التابع قيمة نصيّة تمثّل النص الجديد بعد إجراء عمليّة الاستبدال ضمنه، أي أنّ النص الأساسي يبقى دون تغيير. انظر الشيفرة التالية: string text = "My friend Mohammad is a developer, Mohammad likes C#."; string newText = text.Replace("Mohammad", "Amjad"); بعد التنفيذ سيحمل المتغيّر newText القيمة النصيّة التالية: "My friend Amjad is a developer, Amjad likes C#." وسيبقى النص الأصلي text على حاله دون تغيير. استخلاص النصوص وضمها استخلاص النصوص يمكننا استخلاص جزء من نص باستخدام التابع SubString والذي يعني نصًّا فرعيًّا أو جزئيًّا. لهذا التابع شكلان. يسمح الشكل الأوّل باستخلاص نص جزئي ابتداءً من دليل محدّد حتى آخر النص. أمّا الشكل الثاني فيسمح أيضًا باستخلاص نص جزئي ابتداءً من دليل محدّد ولكن بطول محدّد أيضًا. للتمييز بين هاتين الحالتين لنكتب بعض الشيفرة: string text = "My friend Mohammad is a developer, Mohammad likes C#."; string text1 = text.Substring(24); بعد التنفيذ سيحتوي المتغيّر text1 على النص: ".#developer, Mohammad likes C". أمّا إذا استخدمنا الشيفرة التالية: string text = "My friend Mohammad is a developer, Mohammad likes C#."; string text1 = text.Substring(24, 9); فسيحتوي المتغيّر text1 على النص: "developer" فقط. والسبب في ذلك أنّنا بدأنا عمليّة الاستخلاص من الدليل 24 (دليل الحرف d) وبطول 9 محارف فقط مما يعني استخلاص الكلمة developer فحسب. ضم النصوص يمكن ضمّ النصوص اعتبارًا من نصوص أصغر باستخدام عامل الضم + حيث أنّ استخدامه بسيط. انظر الشيفرة البسيطة التالية: string text = "My name is " + "Husam"; بعد تنفيذ هذه العبارة سيحتوي المتغيّر text على النص: "My name is Husam" هناك أمرٌ بسيط لكنّه مهم جرى وراء الكواليس! لقد أنشأ مترجم سي شارب كائنًا نصيًّا جديدًا ليستوعب النص الجديد، ثم وضع مرجعًا لهذا الكائن ضمن المتغيّر text. قد لا يبدو الأمر مقلقًا في حالة مثالنا البسيط هذا، ولكن تخيّل معي ماذا سيحدث في برنامج يتطلّب ضمّ مئات من النصوص مع بعضها (وهذا أمر وارد جدًّا)؟ ستحدث بالتأكيد مشاكل في الأداة، وستغص الذاكرة بمئات الكائنات النصيّة التي لا لزوم لها، والتي تنتظر دورها في التنظيف من قبل جامع النفايات GC الذي يعمل على تحرير ذاكرة تطبيقات دون نت من الكائنات غير المستخدمة في البرنامج. الحل الأمثل في هذه الحالة هو تجنّب استخدام عامل الضم (+)، واستخدام الصنف StringBuilder الموجود ضمن نطاق الاسم System.Text الذي يحل هذه المشكلة بكفاءة عالية. لنستعرض البرنامج Lesson11_01 لهذا الغرض: 1 using System; 2 using System.Text; 3 4 namespace Lesson11_01 5 { 6 class Program 7 { 8 static void Main(string[] args) 9 { 10 StringBuilder sb = new StringBuilder(); 11 string[] arrText = { 12 "C# is a powerful language.", 13 "It contains advanced features.", 14 "It makes programming tasks more easier.", 15 "C# is the main programming language in .NET world." 16 }; 17 18 foreach(string text in arrText) 19 { 20 sb.Append(text); 21 } 22 23 Console.WriteLine(sb.ToString()); 24 } 25 } 26 } أنشأنا المتغيّر sb من النوع StringBuilder وأسندنا إليه كائنًا من هذا النوع في السطر 10. بعد ذلك أنشأنا المصفوفة arrText بطريقة مختصرة في السطر 11. ثمّ استخدمنا حلقة foreach للمرور على جميع عناصر المصفوفة arrText وإضافتها واحدًا تلو الآخر إلى المتغيّر sb من خلال التابع Append الذي يتطلّب وسيطًا نصيًّا واحدًا (السطر 20). أخيرًا يعمل التابع WriteLine في السطر 23 على طباعة المحتوى النصيّ الناتج من ضمّ جميع النصوص التي أضفناها باستخدام التابع Append وذلك من خلال استدعاء التابع ToString من المتغيّر sb، ستلاحظ بعد تنفيذ البرنامج أنّ النص المعروض سيكون مضمومًا كما لو استخدمنا عامل الضم (+) على الشكل التالي: C# is a powerful language.It contains advanced features.It makes programming tasks more easier.C# is the main programming language in .NET world. كان من الممكن استخدام تابع آخر من المتغيّر sb في السطر 20 وهو التابع AppendLine. يشبه هذا التابع Append تمامًا باستثناء أنّه يضيف محرف سطر جديد n\ تلقائيًّا إلى كلّ نص جديد تتم إضافته. ملاحظة استخدمنا في السطر 11 أسلوبًا مختصرًا في إنشاء المصفوفات. يمكن استخدام هذا الأسلوب عندما تكون عناصر المصفوفة معروفة ومحدّدة. للأسلوب المختصر الشكل التالي بالنسبة للمصفوفات النصيّة: string[] arrText = {"Text_1", "Text_2", "Text_3", … , "Text_n"}; ويمكن بالطبع استخدام هذا الأسلوب المختصر مع أيّ نوع مصفوفة آخر. تمارين داعمة تمرين 1 ليكن لدينا النص التالي: "black cat and white dog are friends. black cat always brings food to dog, and white dog thanks it." المطلوب كتابة برنامج يحسب عدد الكلمات black وعدد الكلمات dog الموجودة في النص. ثمّ يستبدل كل كلمة white في النص بكلمة brown ويعرض النص المعدّل على الشاشة. تمرين 2 هذا التمرين هو تحدٍّ من نوع آخر! اكتب برنامجًا يطلب من المستخدم نص كيفيّ. ثم أعدّ تقريرًا يتضمّن إحصائيّات حول عدد كل كلمة أدخلها المستخدم، واعرض هذا التقرير على الشاشة. (تلميح: ربما تحتاج إلى شكل مختلف للتابع IndexOf يتطلّب وسيطين: الأوّل هو النص المراد البحث عنه، والثاني هو دليل المحرف الذي سيبدأ البحث اعتبارًا منه. في أمثلتنا السابقة كنّا نبحث افتراضيًّا من المحرف ذو الدليل 0). الخلاصة تعرّفنا في هذا الدرس على الخطوات الأساسيّة في التعامل مع النصوص. حيث تعلّمنا كيف نبحث عن نص محدّد ضمن نص آخر وذلك بأسلوبين مختلفين، بالإضافة إلى إجراء عمليّات استبدال داخل نص. كما تعلّمنا كيف نستخلص جزءًا محدّدًا من نص، وكيف نضمّ النصوص باستخدام الصنف StringBuilder. يُعتبر العمل مع النصوص أساسيًّا ومهمًّا لكلّ مبرمج وخصوصًا في مثل هذه الأيّام، فالبيانات التي يتمّ تبادلها بين التطبيقات المختلفة عبر شبكة الإنترنت تكون على شكل نصوص. سنتناول في الدرس القادم كيفيّة التعامل مع الملفات النصيّة من خلال القراءة والكتابة منها وإليها.
×
×
  • أضف...