ما هو Reg-Free COM - استخدام COM بلا تسجيل

· آخر تحديث: · · COM, Reg-Free COM, Registration-Free COM, تطوير Windows, تقنيات قديمة

سجل التعديلات (3 تحديثات، آخر تحديث 3 Sep، 2026)

سجل بالتغييرات التي أُجريت على هذا المقال. وحيثما حُفظت نسخة سابقة، تبقى متاحة للقراءة عبر رابط دائم يحمل معرّف DOI.

أُضيفت روابط الاستشارة الموجودة في الأصل الياباني (consultation_services). ولم يتغيّر نصّ المقالة نفسه. قراءة النسخة السابقة لهذا التحديث (DOI: 10.5281/zenodo.22240856)
أُعيدَت الترجمة العربية كترجمة كاملة عن النص الياباني الأصلي، وأُضيفَت خريطة المعرفة.
أعيدت الترجمة كترجمة كاملة عن النص الياباني الأصلي. كانت النسخة العربية السابقة مختصراً يسقط أبواباً وجداول ورسوم Mermaid وتعليقات الأشكال وFAQ. أُعيدت هذه العناصر وفق الأصل الياباني، والادّعاءات التقنية مطابقة للنسخة اليابانية.
النشر الأول
الاستشهاد بهذا المقال(DOI: 10.5281/zenodo.21621404)

هذا المقال محفوظ على Zenodo. يرد أدناه معرّف DOI الذي يشير دائمًا إلى أحدث نسخة، ومعرّف DOI المثبَّت على النسخة التي تقرؤها.

小村 豪 (2026). ما هو Reg-Free COM - استخدام COM بلا تسجيل. شركة كومورا سوفت ذ.م.م.. https://doi.org/10.5281/zenodo.21621404 https://comcomponent.com/ar/blog/2026/03/16/011-what-is-reg-free-com/

DOI (أحدث نسخة)
10.5281/zenodo.21621404
DOI (هذه النسخة)
10.5281/zenodo.22279822

في مشاريع COM / ActiveX / OCX تظهر المشكلة نفسها عند كل نشر وتحديث.

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

ما يقلّل هذا العناء كثيراً هو Reg-Free COM. غير أنه رغم الاسم ليس «سحراً يزيل كل عناء COM». ما يزول أساساً هو العناء المرتبط بالتسجيل العام. صعوبات bitness والـ DLL التابعة ومكتبة الأنواع ونموذج الخيوط لا تزول.

ما يزول مع Reg-Free COM وما يبقىيبين المخطّط أن ما يزيله Reg-Free COM أساساً هو العناء المرتبط بالتسجيل العام، وأن صعوبات bitness والـ DLL التابعة ومكتبة الأنواع ونموذج الخيوط لا تزول.Reg-Free COMيقلّ عناء التسجيل العامتبقى صعوبات أيضاًbitness / DLL تابعة / مكتبة أنواع

الشكل 1: ليس سحراً؛ افصل العناء الذي يزول عن العناء الذي يبقى ثم توقّع.

ترتّب هذه المقالة Reg-Free COM أساساً في سياق حبس COM DLL / OCX محلياً داخل تطبيق سطح مكتب Windows.

الجمهور المستهدف والافتراضات

المقالة موجّهة إلى المطوّر الذي يوزّع تطبيق سطح مكتب Windows يستخدم COM DLL / OCX قائم، ويريد الخروج من regsvr32 وصلاحيات المسؤول. الافتراض أنك لمست أساسيات COM (CLSID، ProgID، CoCreateInstance، خادم in-proc) مرّة على الأقل. إن كان ذلك لا يزال غامضاً فأسرع أن تقرأ أولاً «ما هي COM / ActiveX / OCX - دليل عمليّ للفروق والعلاقات بينها».

جزء الإجراءات يستخدم mt.exe وsxstrace من Windows SDK، لذا نفترض بيئة فيها Visual Studio أو Windows SDK.

1. الخلاصة أولاً (بكلمة)

إن قلناها بخشونة مفيدة، فهي كالتالي.

  • Reg-Free COM أسلوب يحمل معلومات تسجيل COM في بيان بدل السجل
  • في وقت التشغيل يُنظر أولاً إلى سياق التنشيط عند حل CoCreateInstance أو CLSIDFromProgID
  • بذلك يمكن إبقاء COM DLL / OCX خاصة بكل تطبيق
  • المزايا الرئيسة: سهولة النشر بأسلوب XCOPY، وسهولة تجنّب تصادم الإصدارات، وصعوبة كسر إلغاء التثبيت
  • غير أن مشكلة 32-bit / 64-bit لا تزول. لا تُتفادى بطريقة كتابة البيان
  • كما يلزم التفكير على حدة في الـ DLL التابعة ومكتبة الأنواع والمرجع وقت التصميم والاعتماد على تسجيل غير قياسي
  • عملياً التوافق جيد جداً عندما تريد وضع مكوّن COM خاص بالتطبيق بجانبه

باختصار، Reg-Free COM آليّة تعيد تنشيط COM إلى مستوى التطبيق.

موضع معلومات التسجيل يتغيّريبين المخطّط أن Reg-Free COM يحمل معلومات تسجيل COM في بيان بدل السجل، وأن سياق التنشيط يُنظر إليه أولاً عند حل CoCreateInstance ونحوه، فيمكن إبقاء مكوّن COM خاصاً بكل تطبيق.حمل معلومات التسجيل في بيانسياق التنشيط أولاً عند الحليمكن إبقاء مكوّن COM خاصاً بكل تطبيقيسهل النشر بأسلوب XCOPY وتجنّب التصادم

الشكل 2: الجوهر أن مدخل الحل ينتقل من السجل إلى البيان.

في المخطّط، يشير الخطّ المتّصل إلى علاقة قائمة دائماً، ويشير الخطّ المتقطّع إلى علاقة مشروطة (شروط قيامها مذكورة في شرح كلّ علاقة في الصفحة التفصيليّة). القائمة الكاملة للعلاقات (المجموع 26، مع الأدلّة ودرجة اليقين) وتعريفات المفاهيم الرئيسة مجمّعة في صفحة تفاصيل خريطة المعرفة (باليابانية). البيانات: JSON-LD / Turtle

2. ما نعنيه بـ Reg-Free COM في هذه المقالة

Reg-Free COM اختصار Registration-Free COM. قد يُكتب بالعربية «COM بلا تسجيل».

«بلا تسجيل» هنا تعني عدم الاعتماد الكلّي على تسجيل سجل عام مثل HKCR / CLSID / InprocServer32 لاستخدام COM. لا تعني أن COM نفسه يزول، ولا أن GUID يصير غير لازم.

ما تستهدفه هذه المقالة أساساً أمور كهذه.

  • COM DLL أصلي
  • خادم COM مبني على ATL
  • ActiveX / OCX
  • التشغيل المتبادل لـ COM المبني على .NET Framework
  • النشر عبر COM host في .NET 5+ / .NET 8

عكس ذلك، ما نريد تأكيده هنا نقطتان.

  1. Reg-Free COM حديث «تنشيط»
  2. توزيع معلومات الأنواع وإعداد المرجع وقت التصميم قد يبقيان موضوعاً منفصلاً

خلط هذين يعكّر الحديث كثيراً.

موضوعان لا يجوز خلطهمايبين المخطّط أن Reg-Free COM حديث تنشيط، وأن توزيع معلومات الأنواع والمرجع وقت التصميم قد يبقيان موضوعاً منفصلاً، فخلط الاثنين يعكّر الحديث.Reg-Free COMحديث تنشيطتوزيع معلومات الأنواع ومرجع وقت التصميميبقيان موضوعاً منفصلاًالخلط يعكّر الحديث

الشكل 3: افصل حديث وقت التشغيل عن حديث وقت التصميم من البداية.

3. ترتيب في لوحة واحدة أولاً

قبل الدخول في الشكل نعرّف مسبقاً أربع كلمات تتكرّر في هذه المقالة.

المصطلح المعنى
سياق التنشيط (activation context) بنية بيانات وقت التشغيل تحفظ «أي إصدار من أي assembly يستخدمه هذا الخيط الآن». ينظر CoCreateInstance إليها قبل السجل
side-by-side assembly آليّة Windows لإبقاء مكوّنات بالاسم نفسه بإصدارات مختلفة على الجهاز نفسه. تُعرَّف بالبيان، وassemblyIdentity بمثابة بطاقة الاسم
بيان التطبيق XML يُرفق بجانب EXE ويكتب «على أي side-by-side assembly أعتمد»
بيان المكوّن (assembly manifest) XML يُرفق بجانب المكوّن ويكتب «أي ملفات يتضمّن هذا assembly وأي أصناف COM ينشر». المعلومات التي كانت في السجل تأتي إلى هنا

سياق التنشيط يُحمل لكل خيط. يسلّم COM سياق تنشيط خيط الإنشاء إلى خيط المضيف ثم يستدعي LoadLibrary أو DllGetClassObject، فلا يلزم تجهيز خاص في جانب الاستدعاء.

بعد ذلك أسرع أن ترى الصورة الكاملة في لوحة واحدة.

MyApp.exeApplication ManifestdependentAssemblyComponent / Assembly Manifestfile / comClass / typelibVendorControl.dll / .ocxActivation ContextCLSIDFromProgID / CoCreateInstance

الشكل 4: من بيان التطبيق تُتبع بيان المكوّن فتصل إلى الـ DLL دون استخدام السجل.

في COM المعتاد، عند CoCreateInstance يُتبع السجل لتقرير أي DLL يُحمَّل. في Reg-Free COM يُنظر قبل ذلك إلى سياق التنشيط الساري الآن، ويُحلّ من معلومات البيان المكتوبة هناك.

لذلك حتى على الجهاز نفسه يسهل أن يحمل التطبيق A والتطبيق B إصدارين مختلفين من مكوّن COM من السلالة نفسها. إحساس بإعادة ثقافة مشاركة COM قليلاً نحو محلية التطبيق.

4. لماذا يثقل نشر COM المعتاد

ثقل نشر COM المعتاد ليس لأن COM نفسه سيئ، بل لأن هناك افتراض تسجيل عام.

لاستخدام صنف COM تلزم تقريباً معلومات كهذه.

المعلومة الدور
CLSID GUID يعرّف الصنف تعريفاً فريداً
ProgID اسم يسهل على الإنسان التعامل معه
InprocServer32 أي DLL يُحمَّل
ThreadingModel افتراض مثل Apartment / Both
TypeLib معلومات الأنواع

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

غير أن هذه المشاركة تنقلب عملياً.

  • إعداد منتج يكتب فوق تسجيل COM لمنتج آخر
  • مزيل التثبيت «ظن أنه حذف ما يخصّه فقط» فيكسر COM مشتركاً
  • تسجيل موجود مصادفة على جهاز المطوّر غير موجود على جهاز الإنتاج
  • تسجيل 32-bit و64-bit لا يتطابقان، فينزاح الظاهر وحده على نحو غريب

أي أن نموذج النشر يُحرج الناس أكثر من COM نفسه في كثير من الأحيان. Reg-Free COM آليّة لتقليل عناء نموذج النشر هذا.

كيف تنقلب المشاركة العامةيبين المخطّط أن دخول معلومات تسجيل COM إلى السجل يسهّل المشاركة على مستوى الجهاز، لكنها تنقلب عملياً إلى كتابة فوق من منتج آخر أو جرّ عند إلغاء التثبيت أو فرق بيئة بين جهاز المطوّر وجهاز الإنتاج، فنموذج النشر يُحرج الناس أكثر من COM نفسه.مشاركة معلومات التسجيل على مستوى الجهازمريح لأن تطبيقات متعدّدة تستخدمهعملياً تنقلب المشاركةكتابة فوق / جرّ / فرق بيئةنموذج النشر يُحرج الناس

الشكل 5: حقيقة العناء ليست COM نفسه، بل افتراض التسجيل العام.

5. كيف يعمل Reg-Free COM

5.1 كتابة التبعيات في بيان التطبيق

أولاً يكتب جانب التطبيق في بيان التطبيق على أي side-by-side assembly يعتمد.

هذا البيان يمكن التعامل معه بأي من:

  • وضعه بجانب EXE مثل MyApp.exe.manifest
  • تضمينه مورداً في EXE

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

وإن وُجدت النسختان الخارجية والمضمَّنة، يُقدَّم البيان على نظام الملفات.

5.2 كتابة معلومات COM في بيان المكوّن

ثم يحمل جانب COM المعلومات التي كانت في السجل في بيان المكوّن.

يدخل هنا مثلاً معلومات كهذه.

  • comClass
  • clsid
  • progid
  • threadingModel
  • typelib
  • وإن لزم proxy / stub أو window class وغيرها

أي تصوّر وصف هيئة COM بـ XML بدل السجل.

هذا البيان يمكن تكوينه بأي من:

  • وضعه ملفاً منفصلاً عن الـ DLL
  • تضمينه مورداً في الـ DLL

عملياً التضمين في الـ DLL كـ private assembly أقل حوادث في الغالب. التشغيل بملف منفصل أوضح، لكنه يسهّل التعثّر في مقابلة اسم الملف وassemblyIdentity، ومكان الوضع، ونسيان النسخ.

كيف يُحمل بيان المكوّنيبين المخطّط أن بيان المكوّن يحمل بـ XML معلومات كانت في السجل مثل comClass وclsid وtypelib، ويمكن وضعه ملفاً منفصلاً عن الـ DLL أو تضمينه مورداً في الـ DLL، وأن التضمين أقل حوادث عملياً.حمل معلومات كانت في السجل بـ XMLوضعها ملفاً منفصلاًتضمينها في الـ DLLيسهّل التعثّر بنسيان النسخ ونحوهأقل حوادث عملياً في الغالب

الشكل 6: المحتوى واحد، لكن اختيار موضع الحمل يغيّر معدّل الحوادث.

5.3 في وقت التشغيل يُنظر أولاً إلى سياق التنشيط

جوهر Reg-Free COM هنا.

عندما يستدعي التطبيق CLSIDFromProgID أو CoCreateInstance ينظر وقت تشغيل COM إلى سياق التنشيط الساري. إن وُجدت معلومات ProgID → CLSID وCLSID → DLL اللازمة هناك أمكن الحل دون السجل.

عكس ذلك، إن نقصت المعلومات اللازمة في البيان سقط إلى الحلّ القائم على التسجيل المعتاد. بسبب هذا السلوك يقع فخ العمل مصادفة على جهاز المطوّر. ظننت أنك صرت Reg-Free، بينما الحقيقة أن التسجيل المحلّي يساعدك.

هذا أكره مطب في Reg-Free COM.

فخ السقوط إلى الحلّ القائم على التسجيليبين المخطّط أنه عند حل CoCreateInstance يُنظر أولاً إلى سياق التنشيط، لكن إن نقصت المعلومات اللازمة في البيان سقط إلى الحلّ القائم على التسجيل المعتاد، فيعمل على جهاز المطوّر مصادفة بمساعدة التسجيل المحلّي.تكفيلا تكفيالحل ينظر إلى سياق التنشيط أولاًهل تكفي المعلومات في البيان؟الحل دون السجلالسقوط إلى الحلّ القائم على التسجيلفخ العمل مصادفة على جهاز المطوّر

الشكل 7: السقوط الصامت إلى الاحتياطي أكبر مطب في هذه الآليّة.

6. ما المكاسب

مزايا Reg-Free COM واضحة جداً عملياً.

6.1 سهولة النشر بأسلوب XCOPY

يمكن جمع الملفات اللازمة في مجلد التطبيق، فيخفّ المثبّت ومعالجة التسجيل. طبعاً الكتابة تحت Program Files حديث صلاحيات منفصل، لكن على الأقل يسهل تقليل عمل المسؤول لأجل تسجيل COM.

6.2 سهولة تقليل تصادم الإصدارات

حتى إن وُجدت إصدارات متعدّدة من مكوّن COM على الجهاز نفسه، يسهل فصل الإصدار الذي يستخدمه كل تطبيق. يسهل كثيراً تجنّب حادث تغيّر السلوك فجأة بسبب إعداد منتج آخر.

6.3 كثيراً ما لا يلزم تغيير الشيفرة القائمة تغييراً كبيراً

Reg-Free COM آليّة تغيّر طريقة الحل أكثر مما تغيّر طريقة استدعاء الشيفرة القائمة من الجذر. لذا إن ناسبت أمكن إدخالها دون لمس شيفرة جانب CoCreateInstance تقريباً.

6.4 يسهل الحذف والتراجع

الحبس على مستوى التطبيق يجعل التحديث والتراجع صادقين كثيراً. في الطرف، يسهل اتخاذ تصوّر استبدال المجلد كلّه.

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

الشكل 8: المزايا كلّها نابتة من خاصية واحدة هي الحبس.

7. المشاهد المناسبة وغير المناسبة

7.1 المشاهد المناسبة

في حالات كهذه يكون Reg-Free COM خياراً قوياً جداً.

الوضع التوافق
تريد تضمين COM DLL / OCX خاص بالتطبيق ممتاز جداً
تريد تعايش إصدارات متعدّدة على الجهاز نفسه ممتاز جداً
تريد تجنّب حوادث تسجيل مكوّن بائع جيد
تريد استخدام ActiveX / OCX استخداماً خاصاً في تطبيق سطح مكتب قائم جيد
تريد تخفيف النشر دون تغيير الاستدعاء القائم تغييراً كبيراً جيد

نموذجياً التوافق جيد مع تطبيق سطح مكتب للأعمال، وأداة ربط أجهزة، وأصول VB6 / MFC / WinForms القائمة.

7.2 مشاهد غير مناسبة أو ينبغي النظر إليها بحذر

من جهة أخرى توجد حالات يستحسن النظر إليها بحذر.

الوضع تعليق
تريد مشاركة COM على مستوى الجهاز كله فائدة Reg-Free ضعيفة
bitness غير متطابق لا يحلّه Reg-Free
اعتماد قوي على معلومات تسجيل غير قياسية أو إعداد خاص يصعب تحويله إلى بيان
توزيع الـ DLL التابعة ووقت تشغيل VC++ غير مرتّب يسقط في موضع آخر في النهاية
أدوات وقت التصميم أو إعداد مرجع IDE يفترض السجل يلزم تصميم تشغيل منفصل

النقطة الأخيرة مهمة خصوصاً. Reg-Free COM يساعد التنشيط في وقت التشغيل، لكنه لا يغيّر دفعة واحدة ما تفترضه واجهة إعداد المرجع وقت التصميم.

وقت التشغيل يُعان ووقت التصميم يبقىيبين المخطّط أن Reg-Free COM يساعد التنشيط في وقت التشغيل، لكن إن افترضت أدوات وقت التصميم أو إعداد مرجع IDE السجل لم يتغيّر ذلك كما هو ويلزم تصميم تشغيل منفصل.التنشيط في وقت التشغيلReg-Free يعينواجهة إعداد المرجع وقت التصميمقد تفترض السجليلزم تصميم تشغيل منفصل

الشكل 9: حتى إن استوى نظام التشغيل، نظام التطوير يُرتَّب على حدة.

8. سوء فهم شائع

8.1 مع Reg-Free COM تزول مشكلة bitness

لا تزول. عملية 32-bit لا تحمّل إلا COM DLL من نوع in-proc بـ 32-bit، وعملية 64-bit لا يدخلها إلا DLL بـ 64-bit. هذا كما كان مع Reg-Free.

8.2 مع Reg-Free COM لا يُنظر إلى السجل أصلاً

هذا أيضاً غير صحيح. إن نقصت المعلومات اللازمة في البيان سقط إلى الحلّ القائم على التسجيل المعتاد. لذا النجاح على جهاز المطوّر ≠ صحة تكوين Reg-Free ليس مضموناً.

8.3 مع Reg-Free COM تُسوّى أيضاً قصة مكتبة الأنواع تلقائياً

هذا صحيح نصفه فقط. يمكن كتابة معلومات typelib في البيان أيضاً، لكن إعداد مرجع VBA، و#import في C++، وتوليد المرجع وقت التصميم في جانب .NET أمور تحتاج تصميماً منفصلاً في العادة.

Reg-Free COM أولاً حديث جعل التشغيل ممكناً. كيف تطوّر بأنواع هو الموضوع التالي.

ترتيب حديث التشغيل وحديث الأنواعيبين المخطّط أنه يمكن كتابة معلومات typelib في البيان أيضاً، لكن التعامل مع معلومات الأنواع مثل إعداد مرجع VBA وimport في C++ وتوليد المرجع وقت التصميم في .NET يحتاج تصميماً منفصلاً، وأن Reg-Free COM أولاً حديث جعل التشغيل ممكناً والتطوير بأنواع موضوع تالٍ.تكوين Reg-Free COMاجعل التشغيل ممكناً أولاًثم كيف تطوّر بأنواعإعداد مرجع VBA / import / توليد interop

الشكل 10: إمكان كتابة typelib شيء، واكتمال تشغيل معلومات الأنواع شيء آخر.

8.4 مع Reg-Free COM يمضي أي ActiveX / OCX كما هو

هذا أيضاً خطر. إن ركب المكوّن معلومات تسجيل COM القياسية سهل التقدّم، لكن إن كثف إعداد السجل الخاص، والإعداد الإضافي، ومعالجة الترخيص، والاعتماد على مجموعات وحدات أخرى، صار التحويل إلى Reg-Free عسيراً فجأة.

8.5 Reg-Free COM و.NET Framework / .NET 8 متقاربان تقريباً

هناك تشابه، لكن سلسلة الأدوات مختلفة كثيراً. سياق .NET Framework + RegAsm وسياق .NET 5+ / .NET 8 + comhost أرضيتان مختلفتان حتى مع COM نفسه.

9. الفروق بين الأصلي / .NET Framework / .NET 5+ / .NET 8

هنا يسهل الخلط، لذا نفصل مرّة.

السلالة ترتيب تقريبي
COM DLL / OCX أصلي الأساس التفكير ببيان التطبيق + بيان المكوّن
التشغيل المتبادل لـ COM المبني على .NET Framework يلزم أيضاً بيان جانب المكوّن المُدار إضافة إلى بيان التطبيق بأسلوب Win32
نشر COM في .NET 5+ / .NET 8 يمكن صنع COM host بـ EnableComHosting وتوليد manifest لـ Reg-Free بـ EnableRegFreeCom

9.1 COM المبني على .NET Framework

في COM المبني على .NET Framework يصير البناء من طبقتين: application manifest بأسلوب Win32 لجانب تطبيق COM، وcomponent manifest لجانب المكوّن المُدار.

أي يزيد بيان واحد عن حالة COM الأصلي. قيود الاسم ومعرّف المورد في 10.4 تؤثّر بالمثل في بيان المكوّن هنا.

9.2 نشر COM في .NET 5+ / .NET 8

في .NET 5+ / .NET 8 يصير مدخل نشر COM *.comhost.dll. وإضافة EnableRegFreeCom=true تُخرج بيان side-by-side لـ Reg-Free COM.

أن التعامل مع معلومات الأنواع موضوع منفصل كما في 8.3، وفي .NET Core / .NET 5+ يتغيّر هذا أكثر. لم يعد عالماً يخرج فيه TLB تلقائياً من التجميعة كما في عصر .NET Framework، فإن لزم استخدام مُنَوَّع لزم ترتيب توليد TLB وتضمينه وتسجيله على حدة. الإجراءات المفصّلة في «كيف تستخدم DLL الخاصّة بـ .NET 8 من VBA بـ early binding عبر COM و dscom».

Reg-Free COM في .NET 5 وما بعدهيبين المخطّط أنه من .NET 5 يُصنع comhost.dll مدخل نشر COM بـ EnableComHosting، وأن تفعيل EnableRegFreeCom يُخرج بيان side-by-side لـ Reg-Free COM، لكن توليد TLB وتسجيله يلزم ترتيبهما على حدة.البناء بـ EnableComHostingcomhost.dll يصير المدخلتفعيل EnableRegFreeComيُخرج بيان لـ Reg-Freeالتعامل مع TLB يُرتَّب على حدة

الشكل 11: في .NET 8 تقوم الأرضية بخاصيتين، لكن معلومات الأنواع عمل منفصل.

10. صورة أصغر تكوين

هنا نعرض أصغر صورة يستخدم فيها MyApp.exe ملف Vendor.CameraControl.dll بـ Reg-Free COM.

10.1 صورة تكوين الملفات

MyApp.exe
MyApp.exe.manifest
Vendor.CameraControl.Asm.manifest
Vendor.CameraControl.dll
Vendor.Helper.dll

في المثال أعلاه الافتراض وضع بيان المكوّن ملفاً منفصلاً. يمكن أيضاً التضمين في الـ DLL، وعندئذ تلحق قيود محدّدة باسم assembly ومعرّف المورد. نعالجها مع الإجراءات في 10.4.

10.2 صورة بيان التطبيق

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity
    type="win32"
    name="KomuraSoft.MyApp"
    version="1.0.0.0"
    processorArchitecture="amd64" />

  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Vendor.CameraControl.Asm"
        version="1.0.0.0"
        processorArchitecture="amd64" />
    </dependentAssembly>
  </dependency>
</assembly>

10.3 صورة بيان المكوّن

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity
    type="win32"
    name="Vendor.CameraControl.Asm"
    version="1.0.0.0"
    processorArchitecture="amd64" />

  <file name="Vendor.CameraControl.dll">
    <comClass
      clsid="{01234567-89AB-CDEF-0123-456789ABCDEF}"
      progid="Vendor.CameraControl.1"
      threadingModel="Apartment"
      tlbid="{89ABCDEF-0123-4567-89AB-CDEF01234567}" />

    <typelib
      tlbid="{89ABCDEF-0123-4567-89AB-CDEF01234567}"
      version="1.0"
      helpdir="" />
  </file>
</assembly>

ما يهم حقاً في هذا المثال ليس تفاصيل XML بقدر تطابق dependentAssembly في جانب التطبيق مع assemblyIdentity في جانب المكوّن. إن انزاح هذا صار فشل تشغيل لا يُعرف سببه من ظاهر الخطأ وحده.

لاحظ أن GUID والأسماء أعلاه أمثلة للشرح. عملياً يلزم الكتابة الصحيحة وفق CLSID / TLBID / ProgID / threading model التي ينشرها المكوّن.

متطلّب تطابق البيانينيبين المخطّط أن dependentAssembly في جانب التطبيق وassemblyIdentity في جانب المكوّن يلزم تطابق اسمهما وإصدارهما، وأن الانزاح هنا يجعل فشل تشغيل لا يُعرف سببه من ظاهر الخطأ وحده.يتطابقينزاحdependentAssembly في جانب التطبيقهل يتطابق الاسم والإصدار؟assemblyIdentity في جانب المكوّنيكتمل الحلفشل تشغيل بلا سبب ظاهر

الشكل 12: قبل تفاصيل XML، تطابق بطاقتي الاسم على الجانبين يفصل الحياة عن الموت.

10.4 أين يُوضع البيان وكيف يُضمَّن

هنا أكثر ما يتعثّر في الإجراءات. الاسم المسموح يختلف بحسب الوضع ملفاً منفصلاً أو التضمين في الثنائي.

يبحث side-by-side عن private assembly بهذا الترتيب نسبة إلى مجلد التطبيق.

  1. مجلد WinSxS
  2. <appdir>\<assemblyname>.DLL
  3. <appdir>\<assemblyname>.manifest
  4. <appdir>\<assemblyname>\<assemblyname>.DLL
  5. <appdir>\<assemblyname>\<assemblyname>.manifest

إن وُجد أولاً DLL بالاسم نفسه لاسم assembly توقّف البحث هناك. من هنا لا يكتمل إلا أحد المسارين التاليين.

طريقة الوضع اسم assembly الملف معرّف مورد جهة التضمين
ملف منفصل اسم مختلف عن اسم الـ DLL. مثال: Vendor.CameraControl.Asm ضع Vendor.CameraControl.Asm.manifest بجانب الـ DLL لا تضمّن
تضمين في الـ DLL يجوز أن يكون هو اسم الـ DLL. مثال: Vendor.CameraControl Vendor.CameraControl.dll فقط 1

أي إن استخدمت اسماً مثل Vendor.CameraControl.Asm كما في مثالي 10.2 و10.3 فهذه ممارسة الملف المنفصل. إن انتقلت إلى التضمين فغيّر name في assemblyIdentity إلى Vendor.CameraControl، ووحّد جانب dependentAssembly على الاسم نفسه.

كيف يتوقّف البحثيبين المخطّط أن side-by-side يبحث عن private assembly من WinSxS ثم مجلد التطبيق، وأن العثور أولاً على DLL بالاسم نفسه لاسم assembly يوقف البحث هناك، لذا في تشغيل الملف المنفصل يلزم مخالفة اسم assembly لاسم الـ DLL.وُجدلم يُوجدبدء البحث عن private assemblyالبحث عن DLL بالاسم نفسه لاسم assemblyيتوقّف البحث هناكالبحث عن ملف manifest بالاسم نفسهفي تشغيل الملف المنفصل خالف الاسم

الشكل 13: قيد تسمية الأسماء آتٍ من مواصفة توقّف البحث في المنتصف.

قيد آخر يسهل الخطأ فيه. لا يمكن وضع بيان المكوّن في مورد EXE. ما يمكن وضعه في EXE هو بيان التطبيق.

للتضمين استخدم mt.exe (أداة البيانات) من Windows SDK. نفّذه من موجه أوامر المطوّر في Visual Studio.

rem 1. قبل التضمين، نفِّذ فحص النحو أولاً
mt.exe -manifest MyApp.exe.manifest -validate_manifest
mt.exe -manifest Vendor.CameraControl.manifest -validate_manifest

rem 2. ضمِّن بيان التطبيق في EXE
mt.exe -manifest MyApp.exe.manifest -outputresource:MyApp.exe;#1

rem 3. ضمِّن بيان المكوّن في الـ DLL (معرّف المورد هو 1)
mt.exe -manifest Vendor.CameraControl.manifest -outputresource:Vendor.CameraControl.dll;#1

rem 4. استخرج للتأكّد من نجاح التضمين
mt.exe -inputresource:Vendor.CameraControl.dll;#1 -out:extracted.manifest

مقارنة extracted.manifest المستخرج بالأمر الرابع مع XML الأصلي تقتل «ظننت أنني ضمّنت ولم يدخل».

إجراءات التضمين بـ mt.exeيبين المخطّط تدفّقاً يمرّ فيه أولاً فحص النحو بـ validate_manifest، ثم تضمين بيان التطبيق في EXE، وتضمين بيان المكوّن في الـ DLL بمعرّف مورد 1، وأخيراً الاستخراج والمقارنة مع XML الأصلي للتحقق.أمرّ فحص النحوضمّن جانب التطبيق في EXEضمّن جانب المكوّن في الـ DLL (المعرّف 1)استخرج وقارن مع XML الأصلي

الشكل 14: التضمين دورة إجراءات واحدة تشمل التحقق.

لـ mt.exe نقطتا انتباه.

  • الملفات التي يشير إليها البيان يلزم وضعها في الدليل نفسه الذي فيه البيان. إن كتبت <file name="Vendor.CameraControl.dll"> فضع تلك الـ DLL بجانب البيان ثم نفّذ. إن انفصل خرج البناء عن موضع إدارة البيان توقّف هنا
  • إن حُذف معرّف المورد في -outputresource استُخدم CREATEPROCESS_MANIFEST_RESOURCE (= 1). الأوضح كتابة ;#1 صراحة حتى لا يُحرجك أن يصير 1 دون قصد

إن أردت استبدال ما هو مضمَّن سلفاً فقط أمكن -updateresource:<ملف>;#1. هذا بمعنى تمرير الوسيط نفسه إلى -inputresource و-outputresource.

10.5 إجراءات تحقق تشمل بيئة نظيفة

«عمل على جهاز المطوّر» لـ Reg-Free COM يكاد لا يعني شيئاً. احتمال المساعدة من تسجيل السجل المحلّي يبقى دائماً. تحقّق بهذا الترتيب.

  1. ابنِ واجمع طقم التوزيع كلّه في مجلد واحد. EXE، البيان، COM DLL، الـ DLL التابعة، وقت تشغيل VC++، حتى proxy / stub DLL
  2. جهّز بيئة تحقق. المثالي بيئة لم يُسجَّل فيها COM المستهدف قط. استخدام Windows Sandbox يتيح التجربة من حالة فارغة في كل مرّة
  3. في تلك البيئة تأكد أولاً أن COM المستهدف غير مسجّل. بالأوامر أدناه، إن صار الخطأ بمعنى عدم العثور على المفتاح فهو غير مسجّل
  4. انسخ المجلد وشغّل كما هو. لا تشغّل مثبّتاً ولا regsvr32
  5. تأكد من مرور إنشاء كائن COM. التشغيل وحده لا يتحقق من مكوّن ذي إنشاء مؤجّل. حرّك حتى شاشة أو وظيفة يجري فيها CoCreateInstance فعلاً
  6. إن فشل فاجمع السجلات بإجراءات 11.2

الأوامر المستخدمة في الخطوة 3 هذه.

reg query "HKCR\CLSID\{01234567-89AB-CDEF-0123-456789ABCDEF}" /reg:64
reg query "HKCR\CLSID\{01234567-89AB-CDEF-0123-456789ABCDEF}" /reg:32
reg query "HKCR\Vendor.CameraControl.1"

عرض سجل 32-bit و64-bit شيئان مختلفان، لذا انظر حتماً إلى الجانب الموافق لـ bitness التطبيق. النظر إلى /reg:64 و/reg:32 كليهما أضمن.

إن أردت التجربة على جهاز المطوّر فأزل التسجيل أولاً بـ regsvr32 /u Vendor.CameraControl.dll ثم تحقّق. غير أن بيئة يستخدم فيها منتج آخر COM نفسه تتأثّر، فإعداد بيئة نظيفة أسلم.

تدفّق التحقق في بيئة نظيفةيبين المخطّط تدفّق جمع طقم التوزيع في مجلد واحد، وتجهيز بيئة تحقق لم يُسجَّل فيها COM المستهدف قط، والتأكد أولاً من عدم التسجيل، ثم نسخ المجلد والتشغيل كما هو، وتحريك وظيفة يجري فيها CoCreateInstance حتى التحقق.إن فشلاجمع طقم التوزيعجهّز بيئة تحقق نظيفةتأكد أولاً من عدم التسجيلانسخ وشغّل كما هوحرّك حتى وظيفة يجري فيها إنشاء COMاجمع السجلات وافحص

الشكل 15: إدخال تأكيد عدم التسجيل يُخرج «العمل مصادفة» من التحقق.

11. المطبات

11.1 يعمل على جهاز المطوّر ويفشل عند التوزيع

أول ما ينبغي الشك فيه نمط المساعدة فعلاً من تسجيل السجل. التحقق من Reg-Free COM أسلم إن أمكن في بيئة نظيفة.

11.2 لا يبدأ التشغيل بـ «side-by-side configuration is incorrect»

هذا النوع يقع من عدم اتساق manifest، ونقص DLL تابعة، ونقص وقت تشغيل VC++، وفرق المعمارية وغيرها. نص الخطأ السطحي قليل اللطف جداً، لذا المسار المعتاد التتبع بـ سجل الأحداث وsxstrace.

سجل الأحداث: افتح عارض الأحداث > سجلات Windows > Application، وابحث عن أخطاء مصدرها SideBySide. يظهر هنا عند حل أي assembly وقع الإخفاق.

sxstrace يُؤخذ مع إعادة إنتاج الإخفاق. افتح موجه الأوامر كمسؤول ليكون أضمن.

rem 1. トレースを開始する。このウィンドウは開いたままにする
sxstrace trace -logfile:sxstrace.etl

rem 2. 別のウィンドウでアプリを起動し、失敗を再現させる

rem 3. トレースを止める。1 のウィンドウで Enter を押すか、別ウィンドウから次を実行する
sxstrace stoptrace

rem 4. 生の .etl を人が読める形式へ変換する
sxstrace parse -logfile:sxstrace.etl -outfile:sxstrace.txt

إن لم ترد ظهور موجه الإيقاف فأضف -nostop في الخطوة 1. إن طال الخرج فأضف -filter:MyApp.exe في الخطوة 4 لتضييقه على التطبيق المستهدف فقط.

في sxstrace.txt بعد التحويل يتراصف أي بيان بُحث عنه وأين لم يتطابق. إن أخطأت تسمية الأسماء في 10.4 بان أيضاً هنا من «اسم الملف الذي ذُهب للبحث عنه».

كيف تفحص خطأ side-by-sideيبين المخطّط أنه عند عدم بدء التشغيل بـ side-by-side configuration is incorrect تُؤكَّد أخطاء مصدر SideBySide في عارض الأحداث، ويُبدأ التتبع بـ sxstrace ثم تُعاد إنتاج الإخفاق، وبعد الإيقاف يُحوَّل بـ parse إلى صيغة مقروءة ويُتبع موضع عدم التطابق.أكّد SideBySide في سجل الأحداثابدأ التتبع بـ sxstraceشغّل التطبيق وأعد إنتاج الإخفاقأوقف وحوّل بـ parseاقرأ مواضع البحث وعدم التطابق

الشكل 16: لا تحتَر بنص الخطأ السطحي؛ اتبع مسار الحل بالسجل والتتبع.

11.3 انزياح مقابلة بيان المكوّن وبيان التطبيق

  • الاسم مختلف
  • الإصدار مختلف
  • processorArchitecture مختلف
  • البيان الذي ظننت أنك نسخته قديم

هذا الجانب فرق صغير جداً في الظاهر، ويؤثّر كبيراً جداً عند التشغيل.

11.4 نسيان وضع DLL تابعة

إن اكتفيت بالنظر إلى Vendor.CameraControl.dll سقط ما يُقرأ بعده: Vendor.Helper.dll، ووقت تشغيل VC++، وproxy / stub DLL. يقلّل Reg-Free COM مشكلة تسجيل COM، لكنه لا يزيل حتى مشكلة حل التبعيات الأصلية.

11.5 تأجيل تشغيل مكتبة الأنواع وإعداد المرجع

حتى إن مرّ تنشيط وقت التشغيل فقط، إن صار الأمر:

  • تريد ربطاً مبكّراً من VBA
  • تريد #import في C++
  • تريد صنع interop وقت التصميم في جانب .NET

لزم أسلوب توزيع معلومات الأنواع. Reg-Free COM لا يرتّب هذا كلّه تلقائياً، لذا المهم فصل runtime عن design-time في التفكير.

12. الخلاصة

إن قيل Reg-Free COM بكلمة فهو آليّة تُميل معلومات تسجيل COM من مستوى الجهاز كله إلى مستوى التطبيق.

بذلك توجد مزايا:

  • سهولة حبس COM DLL / OCX محلياً في التطبيق
  • سهولة تقليل تصادم الإصدارات
  • سهولة تبسيط النشر والتراجع

ومن جهة أخرى تبقى مهمة:

  • 32-bit / 64-bit
  • الـ DLL التابعة
  • TLB / إعداد المرجع
  • الاعتماد على تسجيل غير قياسي
  • التحقق في بيئة نظيفة

لذا الموقف الأساس عند إدخال Reg-Free COM كالتالي.

  1. اقطع بأنه حديث activation
  2. افصل موضوعات runtime عن design-time
  3. تحقّق في بيئة نظيفة
  4. وحّد bitness والـ DLL التابعة أولاً

النظر بهذا الترتيب يقلّل الحوادث كثيراً.

الموقف الأساس عند الإدخاليبين المخطّط أنه عند إدخال Reg-Free COM يقلّ الحادث إن نُظر بهذا الترتيب: القطع بأنه حديث تنشيط، وفصل موضوعات وقت التشغيل عن وقت التصميم، والتحقق في بيئة نظيفة، وتوحيد bitness والـ DLL التابعة أولاً.اقطع بأنه حديث activationافصل runtime عن design-timeتحقّق في بيئة نظيفةوحّد bitness والـ DLL التابعة أولاً

الشكل 17: التزام المواقف الأربعة بالترتيب يقلّل حوادث الإدخال كثيراً.

13. مقالات ذات صلة

14. روابط مرجعية

أحدث المقالات التي تشترك في نفس الوسوم. عمّق فهمك بمواضيع مرتبطة.

ترتبط هذه المقالة بشكل طبيعي بصفحات الخدمات التالية.

الأسئلة الشائعة

أسئلة شائعة حول موضوع هذه المقالة.

ما هو Reg-Free COM؟
آليّة تحمل معلومات تسجيل COM في بيان (manifest) بدل السجل، واختصار Registration-Free COM. في وقت التشغيل يُنظر أولاً إلى سياق التنشيط عند حل CoCreateInstance أو CLSIDFromProgID، وتُحلّ الـ DLL من معلومات البيان المكتوبة هناك. بذلك يمكن إبقاء COM DLL/OCX خاصة بكل تطبيق، فيسهل النشر بأسلوب XCOPY، ويقلّ تصادم الإصدارات، ويصعب كسر إلغاء التثبيت.
هل يحلّ Reg-Free COM أيضاً مشكلة 32-bit/64-bit؟
لا يحلّها. عملية 32-bit لا تحمّل إلا COM DLL من نوع in-proc بـ 32-bit، وعملية 64-bit لا يدخلها إلا DLL بـ 64-bit. هذا كما كان مع Reg-Free. كما يلزم التفكير على حدة في توزيع الـ DLL التابعة ووقت تشغيل VC++ ومكتبة الأنواع وإعدادات المرجع وقت التصميم والاعتماد على معلومات تسجيل غير قياسية. ما يزيله Reg-Free COM أساساً هو العناء المرتبط بالتسجيل العام.
لماذا يعمل تكوين Reg-Free COM على جهاز المطوّر ويفشل عند التوزيع؟
أول ما ينبغي الشك فيه نمط المساعدة من تسجيل السجل. إن نقصت المعلومات اللازمة في البيان سقط وقت تشغيل COM إلى الحلّ القائم على التسجيل المعتاد، فيعمل على جهاز المطوّر مصادفة بفضل التسجيل المحلّي. لذا الأسلم التحقق من Reg-Free COM في بيئة نظيفة. إن لم يبدأ التشغيل بـ «side-by-side configuration is incorrect» فالسبب غالباً عدم اتساق البيان أو نقص DLL تابعة، والمسار المعتاد التتبع بسجل الأحداث وsxstrace.
هل يمكن جعل مكوّن COM مصنوع بـ .NET 8 يعمل بـ Reg-Free COM؟
نعم. في .NET 5+/.NET 8 يصنع EnableComHosting ملف *.comhost.dll مدخل نشر COM، وإضافة EnableRegFreeCom=true تُخرج بيان side-by-side لـ Reg-Free COM. غير أن استراتيجية Reg-Free COM وTLB موضوعان منفصلان. في .NET Core/.NET 5+ لا يخرج TLB تلقائياً من التجميعة كما كان في عصر .NET Framework، فإن لزم استخدام مُنَوَّع مثل الربط المبكّر في VBA فالأسلم ترتيب توليد TLB وتضمينه وتسجيله على حدة.

الملف الشخصي للمؤلف

صفحة الملف الشخصي لمؤلف المقالة.

غو كومورا

مؤسّس شركة كومورا سوفت ذ.م.م.

يركّز على تطوير برامج ويندوز، والاستشارات التقنية، والتحقيق في الأخطاء، ويتميّز في المشاريع التي تبقى فيها الأصول القديمة ناشطة، وفي تشخيص الأعطال التي يصعب تحديد سببها.

العودة إلى المدونة