كتابة برنامج خدمة Win2000 باستخدام دلفي
الملخص: يقدم هذا المقال استخدام دلفي لكتابة برامج خدمة Win2000، والفئات المعنية هي TServiceAplicatoin، TService، TServiceThread، إلخ.
الكلمات المفتاحية: الخدمة/ الخدمة
1. مقدمة لخدمات Win2000
تطبيق الخدمة هو برنامج يعمل في الخلفية على WinNT، وقد يحتوي كل تطبيق خدمة على عدة خدمات، وكل خدمة هي إحدى الخيوط (يمكن للخدمة أيضًا إنشاء عدة خدمات فرعية). وباستخدام الخدمات، يمكن للتطبيقات الحصول على أذونات خاصة، ولن يقوم المستخدم بإنهاء البرنامج مباشرة من خلال إدارة المهام Win2000، لذلك غالبًا ما يتم استخدام الخدمات لتحقيق بعض الأهداف الخاصة.
من خلال أداة إدارة الخدمة في لوحة التحكم Win2000، يمكننا ضبط/عرض خصائص الخدمة:
(1) اسم الخدمة (2) اسم العرض (3) الوصف (4) نوع بدء التشغيل؛ (5) التبعيات؛
من بينها، اسم الخدمة يحدد الخدمة.
خذ برنامج C:/WINNT/System32/services.exe الخاص بنظام Win2000 كمثال. يتوافق ملف Exe هذا مع تطبيق الخدمة وهو الكيان المرئي لبرنامج الخدمة؛ ويحتوي ملف exe على خدمات متعددة (خدمة)، مثل Alerter، عميل Dhcp (DHCP) وMessenger وما إلى ذلك. عندما ننهي خدمة ما، لا يتم إنهاء الخدمات الأخرى في تطبيق الخدمة حيث توجد الخدمة.
في دلفي، يزودنا مهندسو بورلاند بـ TServiceApplication و TService و TServiceThread وفئات أخرى، والتي تحتوي على عدد كبير من التفاصيل وتبسط تطوير برامج الخدمة.
2. تطبيق TService
في دلفي، فئة TServiceApplication تتوافق مع ServiceApplication المذكورة أعلاه. باستخدام بيئة تطوير دلفي، نقوم بإنشاء تطبيق خدمة جديد PRoject وإنشاء فئة موروثة من TService. كائن التطبيق في ملف المشروع هو مثيل TServiceApplication. يحتوي كل TServiceApplication على العديد من كائنات TService، والتي تتوافق تمامًا مع العلاقة الكمية المذكورة أعلاه بين برامج الخدمة والخدمات.
من خلال قراءة تعريفات فئات TServiceApplication و TService، يمكننا أن نعرف أن TServiceApplication يرث من فئة TComponent، ويأتي TService من فئة TDataModule، وكائن التطبيق مسؤول عن إنشاء وتدمير كل كائن TService. تتبع الكود التالي
Application.CreateForm(TService1, Service1);
يمكن العثور على أن مالكي كائنات TService التي تم إنشاؤها هم جميع كائنات التطبيق؛ في VCL FrameWork، يكون المالك مسؤولاً دائمًا عن تدمير كل كائن مكون (تعتمد فئة TComponent الخاصة بـ VCL الوضع المركب)، لذلك سوف يقوم TServiceApplication أيضًا بتدمير كل كائن TService.
باتباع رمز TServiceApplication.Run، يمكنك أن تجد أن TServiceApplication يقوم أولاً بتحليل المعلمات قيد التشغيل وتنفيذ تثبيت الخدمة وإلغاء تثبيتها. بعد ذلك، قم بتهيئة مصفوفة ServiceStartTable، التي تحتوي على اسم الخدمة والإدخال قيد التشغيل لكل كائن خدمة؛ وأخيرًا قم بإنشاء كائن TServiceStartThread، وهو كائن مؤشر ترابط، واستدعاء واجهة برمجة التطبيقات: StartServiceCtrlDispatcher من مؤشر الترابط لبدء العديد من الخدمات المحددة في ServiceStartTable؛ يستمر مؤشر ترابط ServiceApplication الرئيسي في تكرار الرسائل ومعالجتها، مثل تلقي طلبات إيقاف/إيقاف الخدمة مؤقتًا.
3. الخدمة
ترث فئة TService من فئة TDataModule، مما يعني أنه يمكننا إضافة عدد كبير من عناصر تحكم VCL لتحقيق وظائف غنية. بالإضافة إلى ذلك، يمكننا أيضًا التعامل مع OnStart وOnPause وOnStop وOnContinue وOnCreate وOnShutDown وغيرها من الأحداث. ما يجب توضيحه هو: OnStop يعني أن الخدمة قد تم إيقافها، وOnShutDown يعني أن ServiceApplication قد توقف عن العمل، مما يعني أن الخدمات الأخرى قد تم إنهاؤها أيضًا، ومعانيهما مختلفة؛
كما ذكرنا سابقًا، يبدأ ServiceApplication كل خدمة عن طريق استدعاء StartServiceCtrlDispatcher. يبدأ StartServiceCtrlDispatcher مدخل TService، وهو TService.Main. يقوم TService.Main بتسجيل الخدمة أولاً ثم يقوم باستدعاء TService.DoStart. يقوم TService.DoStart بإنشاء كائن عضو TServiceThread داخلي، وهو كائن مؤشر ترابط؛ بفحص TServiceThread.Execute، يمكننا أن نعرف أنه عندما نقوم بمعالجة TService1.OnExecute، فإن TService سوف يقوم بتفويض جميع الطلبات إلى كائن عضو TServiceThread للمعالجة تتعامل الطريقة الافتراضية مع كافة الطلبات.
TService.ServiceExecute هو المحتوى الرئيسي لـ TService. لكي تعمل الخدمة بشكل طبيعي، بالإضافة إلى التعامل مع الأهداف التي تحتاج إلى التركيز عليها (مثل الاستماع إلى منفذ معين، أداء مهمة معينة، وما إلى ذلك)، فإنها تحتاج أيضًا إلى الاستجابة للأوامر/الطلبات الخارجية: مثل إنهاء الخدمة وإيقافها مؤقتًا واستئنافها. لذلك، يمكنك التفكير في إنشاء موضوع مخصص لإكمال هذه المهمة والتعامل مع الأوامر/الطلبات الخارجية في ServiceExecute. وبالتالي فإن الكود هو كما يلي:
في حين لم يتم إنهاؤها تبدأ
ServiceThread.ProcessRequests(False);
نهاية؛
بالطبع، يمكنك أيضًا التعامل مع مهام معينة في OnExecute، مثل الاستماع إلى منفذ معين، ولكن هذا غالبًا ما يؤدي إلى عدم قدرة الخدمة على الاستجابة لطلبات الإيقاف/الإيقاف المؤقت والطلبات الأخرى في الوقت المناسب. عند اكتمال OnExecute، تكون الخدمة قد أكملت مهمتها بالفعل وهي على وشك الانتهاء (الإنهاء).
مراجع:
MSDN، رمز مصدر دلفي VCL، وثائق مساعدة دلفي