سؤال

كيف يمكنني تخصيص الموارد عندما يتم قتل العملية ، على سبيل المثال ، مدير المهام؟ هل هناك طريقة لاستدعاء وظيفة قبل إغلاق العملية؟

هل كانت مفيدة؟

المحلول

لا يوجد شيء يمكنك فعله حقًا إذا قتلت عمليتك. بحكم التعريف ، فإن قتل العملية هو ذلك - قتلها. لا تحصل العملية على فرصة لتشغيل أي رمز. هذا كثير جدا "حسب التصميم".

تخيل أنه يمكنك تسجيل روتين تم استدعاؤه عندما تم قتل العملية من قبل المستخدم (أو من خلال عملية أخرى). ماذا ستفعل؟ جميع المواضيع الأخرى في عمليتك ستكون في حالة غير محددة ، كيف يمكنك المزامنة معهم؟ تذكر أن الفكرة هي أن العملية تحتاج إلى قتل.

السيناريو الآخر أكثر صرامة: الكود الخاص بك حميد ويحاول فعل الشيء الصحيح - على سبيل المثال التنظيف وكن مواطنًا جيدًا للنظام. بعض الكود ليس كذلك. تخيل ما نعمة مؤلف البرامج الضارة ، فسيكون ذلك إذا سمح نظام التشغيل بتشغيل الكود لعملية تم قتلها. سيكون الأمر سيئًا بما يكفي للعمليات الخبيثة التي كانت تعمل مع امتيازات المستخدم القياسية ، وفظيعة تمامًا لأي تشغيل مع امتيازات إدارية.

اللمسات الأخيرة على الانتهاء من معالجة الاستثناءات المنظمة لن تحل هذه القضية الأساسية.

في الاتجاه الصعودي ، سيحرر نظام التشغيل جميع الموارد التي يعرفها عندما يتم قتل العملية الخاصة بك ، وهي كائنات الذاكرة والكوتينيل. هذه لن تتسرب. لكن Explorer لا يعرف عن عمليتك ، لذا لا يمكن تنظيفها.

تتمثل إحدى الطرق لحل ذلك في أن يكون لديك عملية مراقبة تتبع حالة العمليات الأخرى وتنظفها. يمكنك القيام بذلك مع عملية بسيطة ، أو مع خدمة. قد تفكر أيضًا في نوع من تمديد القذيفة الذي كان له خيط خاص به فعل الشيء نفسه.

نصائح أخرى

لا توجد طريقة لتنفيذ رمز تعسفي عند الإنهاء في عملية على وشك القتل عن طريق دعوة إلى TerminateProcess, ، مثل مدير المهام ، أو أداة أخرى للعملية مثل Tskill أو TaskKill.

لا نهائيات حرجة ، ولا نهائيات عادية ، ولا يحاول/أخيرًا ، وبالتأكيد ليس مجرد أشياء تنفذ IDisposable يمكن أن يتسبب في تنفيذ رمز في هذا السيناريو. لن يتم استدعاء أحداث فصل DLL من إنهاء العملية عبر TerminateProcess.

أفضل ما يمكنك فعله هو استخدام عملية مراقبة تراقب العملية الأصلية وتنفيذ التعليمات البرمجية ذات الصلة عند إنهاء العملية الأصلية.

من الناحية النظرية ، يجب أن تعامل O/S للموارد بعد مقتل العملية. ما نوع الموارد التي تفكر فيها على وجه الخصوص؟


يحرر:

حسنًا ، من الصعب توضيح ذلك. أنا أستخدم مكتبة تلتف بعض وظائف نظام التشغيل لإدارة بعض ملحقات الصدفة. عندما يغلق التطبيق دون الاتصال بشكل صريح بالطرق المناسبة ، يتجمد جميع المستكشف وأحتاج إلى إعادة تشغيله.

أي DLL غير مُدار (وفقًا للوثائق) من المفترض أن يتم الاحتجاج به مع أ DLL_PROCESS_DETACH حدث؛ ومع ذلك، هذا DLL_PROCESS_DETACH لا يتم استدعاء الحدث عند إنهاء العملية عبر TerminateProcess API.

googling ل هذه الشروط يتحول الشيء الجديد القديم: لماذا لا يمكنك فخ TerminateProcess؟الذي يقول، "بمجرد القتل باستخدام TerminateProcess ، لن يتم تشغيل رمز وضع المستخدم في هذه العملية. لقد ذهب."

نظرًا لأن كل ما تحاول العمل معه (أي .NET ، Explorer ، Shell ، COM) يحدث في وضع المستخدم ، أعتقد أن الإجابة هي أنه لا توجد طريقة لفعل ما تريد.

بدلاً من ذلك ، ربما هناك طريقة أخرى: على سبيل المثال ، عن طريق إضافة رمز إلى امتدادات shell الخاصة بك حتى يدركوا ما إذا كانت عمليتك قد تم تعزيزها.

يمكنك محاولة لف عمليةك بأكملها في بيان المحاولة/أخيرًا (يمكنك وضع الأشياء المحددة في الفقرة الأخيرة) ، ولكن في بعض الحالات لن يكون ذلك كافيًا.

في الواقع ، أعتقد أنه يمكنك تشغيل موضوع خلفية من عمليتك للقيام بكل الأشياء والخيط . بالطبع ، لن يعمل هذا إذا تم إنهاء العملية برمتها لسبب ما.

يمكنك أيضًا تشغيل عملية الطفل وعملية الاتصال. waitforexit () ولكن لست متأكدًا مما إذا كان الشيء المتعلق بالشرق الخاص بك يمكن أن يعمل مع نهج متعدد العمليات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top