سؤال

عند إنشاء عملية طفل في C ++ باستخدام Windows API ، يمكن للمرء أن يسمح براالة المقابض من الوالد إلى الطفل. في مثال Microsoft "إنشاء عملية طفل مع إدخال وإخراج إعادة توجيه", ، إعادة توجيه عملية الأطفال الأمراض المنقولة جنسياً إلى الأنابيب التي أنشأها الوالد ، من الضروري السماح بالميراث أن تكون أنابيب إعادة التوجيه قابلة للاستخدام.

أنا أعمل على فئة تجريبية صغيرة تطلق عملية تنفيذ خارجي ، وتقرأ الإخراج ، ثم يبصقها مرة أخرى على المتصل (الذي يسجل الإخراج الذي تم إرجاعه إلى ملف). أحاول البناء في ميزة مهلة ، حيث سيتم حظرها لفترة معينة فقط من الوقت قبل الاتصال TerminateProcess() على الطفل والاستمرار مع الحياة.

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

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

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

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

شكرا لك أيها الطيب.

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

المحلول

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

يبدو لي أن فئة إنشاء العمليات الخاصة بك يجب ألا تحاول تخمين المتصل الثاني ، الذي فتح الملف بالفعل.

ومع ذلك ، إذا كان لديك معرفة خاصة بالتحديد التي تعالج احتياجات العملية الجديدة ، ثم اعتبارًا من نظام التشغيل Windows Vista ، فهناك آلية لتحديد المقابض التي يجب أن تكون موروثة. عندما تستعد للاتصال CreateProcess, ، إستخدم STARTUPINFOEX بنية بدلا من المعتاد STARTUPINFO. لديها lpAttributeList عضو. تخصيصه وتهيئته ، ثم استخدمه UpdateProcThreadAttribute مع PROC_THREAD_ATTRIBUTE_HANDLE_LIST لتعيين قائمة المقابض المراد أن تكون موروثة. يجب أن تكون جميع المقابض قابلة للوراثات ، ولا تزال بحاجة إلى تحديد bInheritHandles = true عندما تتصل CreateProcess. تحتاج أيضًا إلى تضمين EXTENDED_STARTUPINFO_PRESENT في ال dwCreationFlags معامل. أظهر ريموند تشن هذه التقنية في مقال في عام 2011.

إذا لم تكن هذه الوظيفة المضافة متوفرة لك ، فيمكنك بالتأكيد محاولة [تعداد جميع المقابض المفتوحة لبرنامجك] وتعيين جميع خصائص الميراث معها SetHandleInformation, ، ولكن يبدو أن هذا يتجاوز نطاق الوظيفة التي تتمثل مهمتها في إنشاء عمليات للأطفال. دع الرمز الذي يخلق المقابض يقلق بشأن ما إذا كان ينبغي أن يكون قابلاً للوراثة.

نصائح أخرى

يمكنك استخدام sethandleinformation لمسح HANDLE_FLAG_INHERIT بت على مقبض الإخراج الخاص بك ، فإن هذا سيمنع عملية الطفل من ورثها.

إذا تم تعيين هذه العلامة ، فإن عملية الطفل التي تم إنشاؤها باستخدام معلمة Binherithandles الخاصة بـ CreateProcess Set to True سترث مقبض الكائن.

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