سجل التعديلات (4 تحديثات، آخر تحديث 3 Sep، 2026)
سجل بالتغييرات التي أُجريت على هذا المقال. وحيثما حُفظت نسخة سابقة، تبقى متاحة للقراءة عبر رابط دائم يحمل معرّف DOI.
- أُضيفت روابط الاستشارة الموجودة في الأصل الياباني (consultation_services). ولم يتغيّر نصّ المقالة نفسه. قراءة النسخة السابقة لهذا التحديث (DOI: 10.5281/zenodo.22240814)
- أُعيدَت الترجمة العربية كترجمة كاملة عن النص الياباني الأصلي، وأُضيفَت خريطة المعرفة.
- أعيدت الترجمة كترجمة كاملة عن النص الياباني الأصلي. كانت النسخة العربية السابقة مختصراً يسقط أبواباً وجداول ورسوم Mermaid وتعليقات الأشكال وFAQ. أُعيدت هذه العناصر وفق الأصل الياباني، والادّعاءات التقنية مطابقة للنسخة اليابانية.
- أُضيف DllSurrogate إلى 5.2 بوصفه خيارًا يستحق النظر قبل كتابة ملف EXE مساعد خاص بك. إذا كان المكوّن خادم COM من نوع in-proc، فيكفي إضافة AppID إلى الـ CLSID الخاص به وكتابة DllSurrogate فارغ تحت ذلك الـ AppID لتشغيله خارج العملية دون كتابة سطر واحد من التعليمات البرمجية. غير أنّ الـ surrogate لا يلغي فرق الـ bitness: ما يزول هو قيد وجوب التحميل داخل العملية نفسها فقط، وتصبح الاستدعاءات خارج العملية مع ما يرافقها من تكلفة المارشالينج والاتصال بين العمليات. ويرسم جدول جديد الحدّ بين الحالات التي يكفي فيها الـ surrogate والحالات التي ما تزال تتطلب ملف EXE مساعدًا خاصًا بك، كما أُضيف مرجعان. أمّا خطوات التسجيل نفسها فهي في مقالة أخرى، ويُكتفى هنا بالإحالة إليها. قراءة النسخة السابقة لهذا التحديث (DOI: 10.5281/zenodo.21621340)
- النشر الأول
الاستشهاد بهذا المقال(DOI: 10.5281/zenodo.21621339)
هذا المقال محفوظ على Zenodo. يرد أدناه معرّف DOI الذي يشير دائمًا إلى أحدث نسخة، ومعرّف DOI المثبَّت على النسخة التي تقرؤها.
小村 豪 (2026). كيف تتعامل مع ActiveX / OCX اليوم - جدول قرار للإبقاء أو التغليف أو الاستبدال. شركة كومورا سوفت ذ.م.م.. https://doi.org/10.5281/zenodo.21621339 https://comcomponent.com/ar/blog/2026/03/12/001-activex-ocx-keep-wrap-replace-decision-table/
- DOI (أحدث نسخة)
- 10.5281/zenodo.21621339
- DOI (هذه النسخة)
- 10.5281/zenodo.22279731
المشاريع التي تظهر فيها كلمتا ActiveX / OCX تأتي عادةً بجوّ أثقل قليلاً.
- تطبيق VB6 أو C++ / MFC قديم ما يزال قيد الاستخدام
- SDK لمعدّات صناعيّة أو أجهزة قياس لا يقدّم سوى OCX
- ويب داخليّ يفترض ActiveX ولا يستطيع الخروج من IE mode
- الرغبة في الانتقال من 32bit إلى 64bit، و OCX واحد يرفض
غير أنّ «قديم إذن نرمي الكلّ» و«يعمل إذن نحفظه إلى الأبد» كلاهما فجّ. المهمّ هو التمييز: هل ذلك ActiveX / OCX مجرّد مكوّن واجهة، أم أنّه سطح حدّ يحمل مواصفات أعمال أو مواصفات أجهزة.
تنظّم هذه المقالة، بترتيب يسهّل القرار، ماذا تختار عند العثور على ActiveX / OCX: الإبقاء أو التغليف أو الاستبدال.
الحالات المعنيّة مثلاً:
- تطبيقات سطح مكتب قائمة من نوع VB6 / MFC / WinForms
- ترحيل تدريجيّ نحو C# / .NET
- شاشات قديمة تتضمّن WebBrowser / IE mode
- تطبيقات Windows تتضمّن عناصر تحكّم ActiveX من بائعين
المحتويات
- الخلاصة أوّلاً (بجملة)
- ما تعنيه ActiveX / OCX في هذه المقالة
- جدول القرار الذي يُنظر إليه أوّلاً
- 3.1. الصورة الإجماليّة
- 3.2. قرار الإبقاء
- 3.3. قرار التغليف
- 3.4. قرار الاستبدال
- 3.5. اعتماد المتصفّح يُنظر إليه على حدة
- نقاط يسهل أن تُضلّل القرار
- 4.1. مكوّن واجهة، أم مكوّن يحمل مواصفات
- 4.2. 32bit / 64bit وحدّ العمليّات
- 4.3. التسجيل والنشر والصلاحيّات والترخيص
- 4.4. STA / حلقة الرسائل / الـ callback
- 4.5. هل ثمّة اختبارات، وهل يمكن الرصد
- توصيات حسب الأنماط الشائعة
- 5.1. تطبيق سطح مكتب داخليّ ما يزال مستقرّاً
- 5.2. نقل OCX بـ 32bit إلى جانب 64bit
- 5.3. شاشات تفترض IE / WebBrowser
- 5.4. ActiveX يحمل تحكّم أجهزة أو مواصفات خاصّة
- أنماط مضادّة شائعة
- قائمة فحص لبدء الترحيل
- دليل اختيار تقريبيّ
- الخلاصة
- نوع الاستشارة الذي يلائم هذا الموضوع
- المراجع
في المخطّط، يشير الخطّ المتّصل إلى علاقة قائمة دائماً، ويشير الخطّ المتقطّع إلى علاقة مشروطة (شروط قيامها مذكورة في شرح كلّ علاقة في الصفحة التفصيليّة). القائمة الكاملة للعلاقات (المجموع 24، مع الأدلّة ودرجة اليقين) وتعريفات المفاهيم الرئيسة مجمّعة في صفحة تفاصيل خريطة المعرفة (باليابانية). البيانات: JSON-LD / Turtle
1. الخلاصة أوّلاً (بجملة)
- عند رؤية ActiveX / OCX، أوّل ما يُحكم عليه ليس «هل هو قديم»، بل بما يتحمّله ذلك المكوّن
- إن كان مجرّد مكوّن واجهة، فالاستبدال أسهل نسبيّاً
- إن كان يحمل تحكّم أجهزة أو تقارير أو صيغة ملفّ خاصّة أو عادات تشغيل تراكمت عبر سنوات، فالتغليف أوّلاً أأمن من إعادة التنفيذ فوراً
- إن كان يعمل بثبات على سطح المكتب ونطاق التغيير صغير، فقرار الإبقاء واقعيّ تماماً
- اعتماد ActiveX في المتصفّح يمكن تمديد عمره، لكن مستقبله ضيّق، فالأولى النظر إليه بأولويّة الاستبدال
- لا يمكن تحميل OCX بـ 32bit كما هو في عمليّة 64bit. هذا لا يُتجاوز بالعزيمة
- التسجيل و DLL المعتمدة وامتيازات المدير والترخيص و STA / MTA: الاحتكاك خارج التنفيذ يصير غالباً نقطة الصعوبة
- «إعادة الكتابة الشاملة كيفما اتّفق» و«التجميد الدائم لأنّ الأمر مخيف» كلاهما مرتفع معدّل الحوادث
بمعنى آخر، ترتيب الحكم هكذا.
- ماذا يحمل ذلك OCX
- هل يلزم استخدامه في العمليّة نفسها
- هل يعلق الأمر عند 32bit / 64bit أو التسجيل أو اعتماد المتصفّح
- هل ينبغي بناء حدّ قابل للاختبار قبل الاستبدال
بهذا الترتيب يصبح التنظيم أسهل بكثير.
flowchart TB
accTitle: ترتيب الحكم
accDescr: يُنظر أوّلاً إلى ما يحمله ذلك OCX، ثمّ هل يلزم استخدامه في العمليّة نفسها، ثمّ هل يعلق الأمر عند 32bit/64bit أو التسجيل أو اعتماد المتصفّح، ثمّ هل ينبغي بناء حدّ قابل للاختبار قبل الاستبدال.
s1["ماذا يحمل ذلك OCX"] --> s2["هل تلزم العمليّة نفسها"]
s2 --> s3["هل يعلق bitness أو التسجيل أو المتصفّح"]
s3 --> s4["هل يُبنى حدّ ثمّ يُستبدل"]
الشكل 1: ليس «هل هو قديم»، بل بهذا الترتيب يتّضح الإبقاء والتغليف والاستبدال.
2. ما تعنيه ActiveX / OCX في هذه المقالة
نثبّت أوّلاً استعمال الكلمات في هذه المقالة.
| الكلمة | المعنى في هذه المقالة |
|---|---|
| COM | نموذج مكوّنات متوافق ثنائيّاً على Windows. الأساس للواجهات المكشوفة والتسجيل و Apartment Model وغيرها |
| ActiveX / OCX | في العمل اليوميّ تُستخدمان غالباً للإشارة مجتمعتين إلى عناصر التحكّم المبنيّة على COM وما حولها من أصول. كثيراً ما تشمل عناصر واجهة بامتداد .ocx وأجزاء تُضمَّن في IE أو في حاوية |
| اعتماد WebBrowser / عالم IE | ليس ActiveX نفسه، لكنّه يشمل المتصفّح المضمَّن والربط الذي يفترض «عالم IE». من جهة القرار يصير مشكلة قريبة جدّاً |
بدقّة، ActiveX و COM ليسا الشيء نفسه. غير أنّ نقاط التعثّر في العمل اليوميّ متشابهة إلى حدّ بعيد.
- هل يتطابق 32bit / 64bit
- كيف يُوزَّع التسجيل و DLL المعتمدة
- في أيّ مضيف / حاوية يعمل
- هل يعلق الأمر عند STA أو حلقة الرسائل أو الـ callback
- هل بقي اعتماد على المتصفّح
تعالج هذه المقالة نقاط القرار العمليّة هذه مجتمعة.
flowchart TB
accTitle: نقاط التعثّر في العمل اليوميّ
accDescr: بدقّة ActiveX و COM ليسا الشيء نفسه، لكن نقاط التعثّر متشابهة: تطابق bitness، توزيع التسجيل و DLL المعتمدة، المضيف الذي يعمل فيه، افتراضات STA والـ callback، وبقاء اعتماد المتصفّح.
ax["مشروع ActiveX / OCX"] --> p1["هل يتطابق bitness"]
ax --> p2["توزيع التسجيل و DLL المعتمدة"]
ax --> p3["في أيّ مضيف يعمل"]
ax --> p4["افتراضات STA والـ callback"]
p4 -.-> p5["هل بقي اعتماد على المتصفّح"]
الشكل 2: حتى إن كان ActiveX و COM مختلفين بدقّة، تتركّز نقاط التعثّر العمليّ في هذا النطاق.
ونلخّص مسبقاً الاختصارات التي ستظهر بعد ذلك كأنّها بديهيّة. في قائمة الفصل 7 يُقال «استخرج ProgID و CLSID»، ومن دون فهم ذلك يتعذّر التحرّك.
| المصطلح | القراءة / الاسم الرسميّ | المعنى |
|---|---|---|
| CLSID | Class ID | GUID يشير فريداً إلى تنفيذ مكوّن COM (الصنف). تسجيل السجلّ أيضاً يُدار بهذا القيمة |
| ProgID | Programmatic Identifier | اسم مقروء أُلحق بـ CLSID. سلسلة مثل Excel.Application |
| IID | Interface ID | GUID يشير فريداً إلى واجهة COM. شيء آخر غير CLSID |
| TLB | Type Library | ملفّ يحمل معلومات الأنواع ثنائيّاً: الواجهات والميثودات وأنواع الوسائط. ما يتيح الاستدعاء «بأنواع» من VB6 أو .NET هو وجود هذا الملفّ |
| RegAsm | Assembly Registration Tool | أداة مرفقة بـ .NET Framework. تسجّل تجميعة .NET في السجلّ لتُستخدم من COM |
| AxHost | — | صنف أساسيّ لاستضافة عنصر تحكّم ActiveX على Windows Forms |
| AxImp | ActiveX Control Importer | أداة تولّد تجميعة غلاف لـ Windows Forms من OCX |
| in-proc / out-of-proc | داخل العمليّة / خارج العمليّة | العمل في عمليّة المستدعي نفسها (DLL أو OCX) أو في عمليّة منفصلة (خادم EXE) |
| LocalServer | — | شكل تشغيل خادم COM كـ EXE في عمليّة منفصلة. يمكن به تجاوز حاجز bitness أو عزل الانهيار |
| Reg-Free COM / side-by-side | COM بلا تسجيل | آليّة تحلّ COM بمعلومات مكتوبة في بيان التطبيق، بلا تسجيل في السجلّ |
| ترخيص design-time / runtime | وقت التطوير / وقت التشغيل | في عناصر تحكّم البائعين قد يختلف التعامل مع الترخيص بين لصق العنصر على الشاشة في جهاز التطوير وتشغيله عند التوزيع |
| adapter / facade | — | نمط تصميم يستبدل واجهة API دقيقة قائمة بواجهة أخشن تناسبكم |
| STA / MTA | Single / Multi Threaded Apartment | نموذج الخيوط في COM. يتغيّر الاتفاق حول أيّ خيط يجوز الاستدعاء منه |
3. جدول القرار الذي يُنظر إليه أوّلاً
3.1. الصورة الإجماليّة
النظر أوّلاً إلى هذا الجدول يكفي في الغالب لتحديد الاتّجاه.
| الوضع | الاختيار الأوّل | السبب |
|---|---|---|
| اعتماد على ActiveX في المتصفّح | أميل إلى الاستبدال | Edge نفسه لا يدعم ActiveX، و IE mode موضوع في موقع تمديد العمر |
| OCX يعمل بثبات في تطبيق سطح مكتب، ونطاق التغيير صغير | أميل إلى الإبقاء | تكلفة الهدم الآن أكبر في كثير من الحالات |
| المراد نقل المحيط فقط إلى .NET، وسلوك عنصر التحكّم غير مقروء | أميل إلى التغليف | ترتيب الحدّ أوّلاً أأمن |
| المراد إدخال OCX بـ 32bit كما هو في عمليّة 64bit | تغليف / تغيير البنية | حدّ لا يُتجاوز in-proc |
| يُستخدم مكوّن واجهة فقط، وثمّة بديل | أميل إلى الاستبدال | غالباً يكفي استبدال السطح |
| نهاية دعم البائع أو التوقيع أو التسجيل أو DLL المعتمدة تتسبّب بحادث في كلّ مرّة | أميل إلى الاستبدال | تكلفة التشغيل ظهرت أصلاً كدين تقنيّ |
| يتضمّن تحكّم أجهزة أو تقارير أو بروتوكولاً خاصّاً | أميل إلى التغليف | من دون تثبيت السلوك أوّلاً لا تُقرأ تكلفة الاستبدال |
flowchart TD
start["يوجد ActiveX / OCX"] --> q1{"اعتماد على المتصفّح؟"}
q1 -- "نعم" --> p1["أولويّة الاستبدال — IE mode تمديد عمر فقط"]
q1 -- "لا" --> q2{"مكوّن واجهة أساساً؟"}
q2 -- "نعم" --> q3{"هل ثمّة بديل مكافئ؟"}
q3 -- "نعم" --> p2["النظر في الاستبدال"]
q3 -- "لا" --> p3["التغليف أوّلاً وترتيب الحدّ"]
q2 -- "لا" --> q4{"هل يحمل تحكّم أجهزة أو مواصفات خاصّة أو منطق تقارير؟"}
q4 -- "نعم" --> p4["التغليف أوّلاً — تجهيز الاختبارات ثمّ الاستبدال على مراحل"]
q4 -- "لا" --> q5{"هل التسجيل أو bitness أو النشر مؤلم؟"}
q5 -- "نعم" --> p5["مراجعة البنية — النظر في out-of-proc / ربط بعمليّة منفصلة / Reg-Free COM"]
q5 -- "لا" --> p6["قرار الإبقاء واقعيّ أيضاً"]
الشكل 3: أوّل تفرع هو اعتماد المتصفّح، ثمّ يتحدّد الاتّجاه بحسب مكوّن الواجهة ووجود البديل وحمل المواصفات.
فيما يلي ننظر إلى كلّ نمط بالترتيب.
3.2. قرار الإبقاء
كون الشيء ActiveX / OCX لا يجعله فوراً مرشّحاً للاستبدال. إذا اكتملت شروط كهذه، فالإبقاء هو الأرخص في حالات شائعة.
- نطاق الاستخدام مغلق، وبيئة التشغيل ثابتة (توزيع داخليّ، إرفاق مع الجهاز، وما شابه)
- عنصر التحكّم يعمل بثبات الآن، وطلبات التغيير ليست كبيرة
- البائع ما يزال نشطاً، أو يمكن القيام بأدنى صيانة داخليّاً
- لا اعتماد على المتصفّح، ويكتمل داخل المضيف القائم على سطح المكتب
- لا حاجة إلى تغيير افتراض 32bit / 64bit في المدى القريب
المهمّ هنا أنّ الإبقاء ≠ الإهمال. إن أبقيتم، فالأولى القيام على الأقلّ بما يلي.
- توثيق نظام التشغيل المدعوم و bitness و DLL المعتمدة المطلوبة وخطوات التسجيل كتابةً
- نقل التثبيت والتسجيل والإلغاء من مذكّرات يدويّة إلى سكربت أو مثبِّت
- تجهيز اختبار دخان في بيئة نظيفة
- عدم بعثرة استدعاءات عنصر التحكّم في التطبيق كلّه، وجمعها قدر الإمكان في موضع واحد
الأسوأ هو مواصلة «يعمل فلا نلمسه» عشر سنوات حتى لا يعود أحد قادراً على شرح الافتراضات. كلّما اخترتم الإبقاء، صارت إظهار الافتراضات أهمّ.
flowchart TB
accTitle: قرار الإبقاء وما يرافقه من إظهار
accDescr: قرار الإبقاء ليس إهمالاً، بل يُنفَّذ مع توثيق الافتراضات، وسكربتة خطوات التسجيل، واختبار دخان في بيئة نظيفة، وتجميع مواضع الاستدعاء.
keep["قرار الإبقاء"] --> d1["توثيق الافتراضات كتابةً"]
keep --> d2["سكربتة خطوات التسجيل"]
keep --> d3["تجهيز اختبار دخان"]
keep --> d4["جمع الاستدعاءات في موضع واحد"]
الشكل 4: الإبقاء ≠ الإهمال. كلّما اخترتم الإبقاء، نفّذوا إظهار الافتراضات معه.
3.3. قرار التغليف
في العمل اليوميّ، هذا الاختيار هو الأكثر عملاً.
«التغليف» هنا يعني حبس ActiveX / OCX داخل حدّ ضيّق، وإظهاره للمحيط كـ API جديد أو مكوّن شاشة جديد.
هذا فعّال إلى حدّ بعيد. لأنّ الدخول في إعادة تنفيذ شاملة قبل أن يُقرأ سلوك المكوّن القديم يميل إلى أن يصير عناءً مزدوجاً: التنقيب عن المواصفات وإعادة إنتاج العيوب. الأأمن هو عزل المكوّن القديم أوّلاً وترتيب الحدّ وحده.
flowchart TB
accTitle: بنية خيار التغليف
accDescr: حبس ActiveX / OCX داخل حدّ ضيّق وإظهاره للمحيط كـ API أو مكوّن شاشة جديد يتجنّب العناء المزدوج للتنقيب عن المواصفات وإعادة إنتاج العيوب عند إعادة التنفيذ الشاملة قبل قراءة السلوك.
old["ActiveX / OCX"] --> wall["الحبس داخل حدّ ضيّق"]
wall --> api["الإظهار كـ API جديد"]
api --> app["المحيط يرى النافذة الجديدة فقط"]
wall -.-> safe["تجنّب عناء التنقيب وإعادة الإنتاج"]
الشكل 5: «التغليف» يعزل المكوّن القديم ويبني نافذة جديدة، فيفيد كمرحلة سابقة لإعادة التنفيذ الشاملة.
لأنماط التغليف عدّة أشكال.
| أسلوب التغليف | الحالات التي يلائمها | ما يُنظر إليه |
|---|---|---|
| مضيف WinForms + AxHost / Aximp | التضمين في شاشة سطح مكتب قائمة، أو الإبقاء على شاشات قليلة | STA، الأحداث، اعتماد وقت التصميم، الترخيص |
| EXE مساعد 32bit / COM LocalServer / جسر عمليّة منفصلة | الانتقال إلى جانب 64bit، أو عزل الانهيار | الاتّصال بين العمليّات، ترتيب التشغيل، المراقبة، النشر |
| نافذة توافق COM في جانب .NET | الإبقاء على مستدعي COM القائم مع تحديث المحتوى | IID / CLSID / TLB / طريقة التسجيل / bitness |
بعد تقرير الاتّجاه، نكتب أيضاً أين تكون الخطوة الأولى.
| أسلوب التغليف | أوّل ما يُفعل | الخطوات التفصيليّة |
|---|---|---|
| مضيف WinForms + AxHost | في Visual Studio انقر بزرّ الفأرة الأيمن على صندوق الأدوات ← «اختيار عناصر صندوق الأدوات» ← اختر الهدف من علامة تبويب «مكوّنات COM». من سطر الأوامر استخدم aximp |
فخاخ التسجيل و bitness في تطوير COM/OCX/ActiveX |
| EXE مساعد 32bit / LocalServer | سجّل جانب EXE بـ 32bit كخادم COM، واستدعه من جانب 64bit بأسلوب out-of-proc | دراسة حالة يفيد فيها COM: استدعاء DLL بـ 64bit من تطبيق 32bit |
| Reg-Free COM | اكتب file و comClass في بيان التطبيق، وحلّ المكوّن بلا تسجيل في السجلّ |
ما هو Reg-Free COM: استخدام COM بلا تسجيل |
| نافذة توافق COM في جانب .NET | اكشف جانب .NET لـ COM، وولّد TLB بـ dscom عند الحاجة | استخدام DLL من .NET 8 بأنواع من VBA: كشف COM و dscom TLB |
يُشغَّل aximp من Developer Command Prompt في Visual Studio.
aximp C:\path\to\MyControl.ocx
بهذا يُولَّد اثنان: غلاف قابل للاستدعاء في وقت التشغيل لأنواع COM، وغلاف لـ Windows Forms مشتقّ من AxHost. اسم الملفّ يُحدَّد من ProgID لا من اسم الملفّ الأصليّ، فانتبهوا إلى هذه النقطة وحدها. في مثال وثائق Microsoft، يخرج من msdxm.ocx الملفّان MediaPlayer.dll و AxMediaPlayer.dll. يُضاف الأخير إلى المراجع ويُلصق AxMediaPlayer على النموذج.
flowchart TB
accTitle: ما يولّده aximp
accDescr: عند تمرير OCX إلى aximp يُولَّد غلاف runtime callable لأنواع COM وغلاف Windows Forms مشتقّ من AxHost، ويُضاف الأخير إلى المراجع ويُلصق على النموذج. اسم الملفّ يُحدَّد من ProgID لا من اسم الملفّ الأصليّ.
ocx["OCX المستهدف"] --> tool["تشغيل aximp"]
tool --> rcw["DLL غلاف أنواع COM"]
tool --> ax["DLL غلاف مشتقّ من AxHost"]
ax --> form["الإضافة إلى المراجع واللصق على النموذج"]
tool -.-> name["اسم الملفّ يُحدَّد من ProgID"]
الشكل 6: مخرجات aximp ملفّا DLL، وما يُلصق على النموذج هو غلاف AxHost المشتقّ.
في حالة Reg-Free COM، بيان جانب التطبيق يأخذ في الحدّ الأدنى شكلاً كهذا.
<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="MyApp" version="1.0.0.0" />
<file name="MyControl.ocx">
<comClass
clsid="{01234567-89AB-CDEF-0123-456789ABCDEF}"
threadingModel="Apartment"
progid="MyCompany.MyControl.1" />
</file>
</assembly>
في أسلوب LocalServer، يدخل مسار EXE في السجلّ تحت HKEY_CLASSES_ROOT\CLSID\{CLSID}\LocalServer32. خوادم EXE المصنوعة بـ ATL أو MFC غالباً ما تدعم التسجيل الذاتيّ والإلغاء بالعرف MyServer.exe /regserver و /unregserver. غير أنّ عرض السجلّ ينقسم حسب bitness، فوعي أنّ EXE بـ 32bit يُسجَّل في عرض السجلّ الخاصّ بـ 32bit لازم دائماً.
flowchart TB
accTitle: تسجيل LocalServer وعرض السجلّ
accDescr: في أسلوب LocalServer يدخل مسار EXE في LocalServer32 تحت CLSID، ويمكن التسجيل الذاتيّ بعرف regserver، لكن عرض السجلّ ينقسم حسب bitness، و EXE بـ 32bit يُسجَّل في عرض 32bit.
exe["خادم EXE"] --> reg["تسجيل المسار في LocalServer32"]
reg --> view{"ما bitness الـ EXE؟"}
view -->|"32bit"| v32["التسجيل في عرض 32bit"]
view -->|"64bit"| v64["التسجيل في عرض 64bit"]
الشكل 7: موضع تسجيل LocalServer يتحدّد بعرض السجلّ المنقسم حسب bitness.
الأهمّ خصوصاً عند التغليف هو عدم نسخ الـ API القديمة كما هي بمئتي عنصر. ذلك لا يفعل سوى استيراد الملاءمات القديمة إلى الشيفرة الجديدة كما هي.
عند التغليف، الانتباه إلى ما يلي يحسّن الأمر كثيراً.
- جعل الميثودات بوحدات خشنة
- منع شيفرة الشاشة من لمس OCX مباشرةً
- أخذ السجلّ اللازم عند الفشل في الحدّ
- تقرير مسؤوليّة المهلة وإعادة المحاولة وتحويل الاستثناءات في الحدّ
- جعل الوجهة المستقبليّة قابلة للاستبدال بالواجهة نفسها
قد تريدون الإبقاء على مدخل COM وحده في جانب .NET الجديد. في هذه الحالة يكون الترتيب الواقعيّ «تحديث المحتوى مع الإبقاء على عقد COM فقط». غير أنّه لا يكفي أن تعتمدوا على حسّ عصر .NET Framework بأنّ «RegAsm يكفي كيفما اتّفق». التعامل مع COM host و TLB و bitness و Registry-Free COM في .NET الحاليّ أسهل إن صُمِّم مسبقاً. هذا الجانب مشروح حتّى الخطوات في استخدام DLL من .NET 8 بأنواع من VBA: كشف COM و dscom TLB و ما هو Reg-Free COM: استخدام COM بلا تسجيل.
flowchart TB
accTitle: المسؤوليّات التي تُقرَّر في الحدّ
accDescr: عند التغليف تُجعل الميثودات بوحدات خشنة، ولا تُترك شيفرة الشاشة تلمس OCX مباشرةً، وتُقرَّر في الحدّ مسؤوليّة السجلّ والمهلة وتحويل الاستثناءات، وتُجعل الوجهة المستقبليّة قابلة للاستبدال بالواجهة نفسها.
b["حدّ التغليف"] --> r1["ميثودات بوحدات خشنة"]
b --> r2["أخذ السجلّ في الحدّ"]
b --> r3["المهلة وتحويل الاستثناءات"]
b --> r4["الاستبدال لاحقاً بالنافذة نفسها"]
r1 -.-> ng["عدم نسخ الـ API القديمة بمئتي عنصر"]
الشكل 8: قيمة التغليف في جمع المسؤوليّات في الحدّ، والنسخ الحرفيّ للـ API القديمة لا يُخرج تلك القيمة.
3.4. قرار الاستبدال
ما يلائم الاستبدال أساساً هو الحالات التي تكون فيها قدامة السطح هي المشكلة.
في مثل هذه الحالات يُفضَّل النظر بأولويّة الاستبدال.
- ذلك ActiveX يُستخدم مكوّن واجهة فقط
- البائع يقدّم خلفاً موجّهاً إلى .NET / WPF / WebView2
- اعتماد المتصفّح أو افتراض IE يعوق العمل
- التسجيل أو التوقيع أو امتيازات المدير أو إعدادات الأمن تعثر في كلّ مرّة
- ثمّة اختبارات أو سيناريوهات أعمال يمكن بها التحقّق من التنفيذ البديل
بالمقابل، رمي مكوّن يحمل تحكّم أجهزة أو منطق تقارير دفعة واحدة لمجرّد أنّ مظهره قديم يقود في الغالب إلى الوحل.
إن استبدلتم، فابدؤوا من الواجهة.
- الشبكة
- التقويم
- الشجرة
- جزء عرض المتصفّح
- مساعدة إدخال بسيطة
هذه أسهل نسبيّاً على الاستبدال. في المقابل، ما يبدو واجهة قد يكون كثيف المحتوى.
- ActiveX بائع لتحكّم الأجهزة
- عنصر تحكّم مدمج مع الطباعة أو توليد التقارير
- عنصر تحكّم يتضمّن قراءة صيغة ملفّ خاصّة وكتابتها
- عنصر تحكّم يحمل callback من COM أو افتراضات خيوط
إساءة قراءة هذا الفرق تُفسد تقدير الجهد دفعة واحدة.
flowchart TB
accTitle: تمييز قرار الاستبدال
accDescr: إن استُخدم مكوّن واجهة فقط وثمّة بديل فالاستبدال أسهل، أمّا المكوّن الذي يبدو واجهة لكنّه يحمل تحكّم أجهزة أو تقارير أو صيغة خاصّة أو افتراضات خيوط فمحتواه كثيف، ورميه فوراً يقود إلى الوحل.
q{"ماذا وراء المظهر"}
q -->|"قدامة السطح فقط"| easy["سهل الاستبدال"]
q -->|"كتلة مواصفات"| heavy["الرمي دفعة واحدة يقود إلى الوحل"]
heavy --> wrap["إلى قرار التغليف أوّلاً"]
الشكل 9: ملاءمة الاستبدال تُحسم بالتمييز بين «قدامة السطح» و«كثافة المحتوى».
3.5. اعتماد المتصفّح يُنظر إليه على حدة
هذا إطار مختلف إلى حدّ بعيد.
ActiveX على المتصفّح، بخلاف OCX على سطح المكتب، سبب الاستمرار في تمديده كما هو ضعيف جدّاً.
السبب بسيط: أساس المتصفّحات الحديثة لا يجعل ذلك ساحة رئيسة. Microsoft Edge نفسه لا يدعم ActiveX. في المقابل، يمكن استخدام IE mode كطبقة توافق تشغّل محرّك عالم IE للمواقع المضبوطة، وتشغّل بعض وظائف IE بما فيها ActiveX.
أي أنّ:
- تمديد العمر للتشغيل الآن ممكن
- لكنّه ليس مستقبلاً عريضاً كتصميم طويل الأمد
flowchart TB
accTitle: موضع ActiveX على المتصفّح
accDescr: Microsoft Edge نفسه لا يدعم ActiveX، و IE mode طبقة توافق تستخدم محرّك عالم IE للمواقع المضبوطة، لذا يمكن تمديد العمر للتشغيل الآن، لكنّ المستقبل كتصميم طويل الأمد ليس عريضاً.
bax["ActiveX على المتصفّح"] --> edge["لا يعمل في Edge نفسه"]
bax --> iem["يمكن تمديد العمر بـ IE mode"]
iem --> future["المستقبل الطويل ضيّق"]
future --> rep["النظر بأولويّة الاستبدال"]
الشكل 10: ActiveX المعتمد على المتصفّح يُفصل فيه تمديد العمر عن التصميم الدائم، ويُنظر إليه بأولويّة الاستبدال.
الشيء نفسه يحدث لعنصر تحكّم WebBrowser المضمَّن في تطبيق Windows.
WebBrowser يجرّ عالم IE، فإذا كان المراد عرض HTML فحسب، فمن الطبيعيّ أن يكون WebView2 المرشّح الأوّل للعمل الجديد من الآن.
غير أنّ ما ينبغي الانتباه إليه هنا هو أنّ WebView2 ليس مكوّن استبدال كاملاً لـ WebBrowser.
- سكربتات تفترض IE DOM
- اعتماد على ActiveX
- افتراضات حول
window.external - سلوك يفترض مناطق الأمن أو الإنترانت
هذه لا تنتقل كما هي. إن استبدلتم، لزم إعادة تصميم سطح الربط بين المتصفّح والأصيل أيضاً، لا محرّك الرسم فقط.
flowchart TB
accTitle: ما لا ينتقل إلى WebView2 كما هو
accDescr: WebView2 ليس مكوّن استبدال كاملاً لعنصر تحكّم WebBrowser، فالسكربتات التي تفترض IE DOM واعتماد ActiveX وافتراضات window.external وسلوك مناطق الأمن لا تنتقل كما هي.
wb["من WebBrowser إلى WebView2"] --> ok["عرض HTML وحده يجعله المرشّح الأوّل"]
wb --> ng["ما لا ينتقل كما هو"]
ng --> n1["سكربتات تفترض IE DOM"]
ng --> n2["اعتماد ActiveX"]
ng --> n3["افتراض window.external"]
ng --> n4["سلوك مناطق الأمن"]
الشكل 11: WebView2 قطعة استبدال لمحرّك الرسم، لكنّه لا يرث سطح الربط في عالم IE.
4. نقاط يسهل أن تُضلّل القرار
4.1. مكوّن واجهة، أم مكوّن يحمل مواصفات
هذه هي الأهمّ.
إن كانت شبكة أو تقويماً قديماً، فالنظر في توافق المظهر والأحداث يكفي لتقدّم الحديث كثيراً. أمّا ActiveX الذي يحمل تحكّم أجهزة أو تقارير أو صيغة خاصّة، فخلف المظهر كتلة مواصفات.
حتّى إن بدا «عنصر تحكّم على الشاشة» نفسه، يتّسع النطاق إلى هذا الحدّ.
- مكوّن عرض قائمة فحسب
- مكوّن يرسل أوامر إلى جهاز ببروتوكول خاصّ
- مكوّن ينفّذ داخليّاً المهلة وإعادة الاتّصال وإعادة الإرسال وامتصاص الاستثناءات
- مكوّن يحمل توافق صيغ الطباعة أو التصدير
إعادة تنفيذ الأخير فوراً تصير في الغالب مشروعاً للتنقيب عن المواصفات. هنا التغليف أوّلاً أأمن.
flowchart TB
accTitle: مكوّن واجهة أم مكوّن يحمل مواصفات
accDescr: حتّى إن بدا عنصر تحكّم على الشاشة نفسه، يتّسع النطاق بين مكوّن عرض قائمة فحسب ومكوّن يحمل أوامر الجهاز وإعادة الاتّصال وتوافق التقارير، وإعادة تنفيذ الأخير فوراً تصير مشروعاً للتنقيب عن المواصفات.
look["عنصر تحكّم على الشاشة"] --> ui["مكوّن عرض فحسب"]
look --> spec["مكوّن يحمل كتلة مواصفات"]
ui --> go["النظر في التوافق يكفي لتقدّم الحديث"]
spec --> dig["إعادة التنفيذ فوراً تصير تنقيباً"]
dig --> wrap["التغليف أوّلاً أأمن"]
الشكل 12: أهمّ تمييز. المظهر قد يتطابق، وطريقة التقدّم تتغيّر بوجود كتلة مواصفات خلفه.
4.2. 32bit / 64bit وحدّ العمليّات
هذه تُغفل كثيراً، لكنّها جوهريّة إلى حدّ بعيد.
OCX من نوع in-proc يجب أن يطابق bitness العمليّة التي تحمّله. أي أنّ تحميل OCX بـ 32bit كما هو في تطبيق 64bit غير ممكن.
الخيارات الواقعيّة عندئذٍ تسقط في الغالب على هذا الثالوث.
- الإبقاء مؤقّتاً على تطبيق المضيف بـ 32bit أيضاً
- حبسه في عمليّة 32bit منفصلة، والربط بجانب 64bit عبر IPC أو COM من نوع out-of-proc
- البدء بالاستبدال من المواضع التي يمكن فيها نزع الاعتماد على ذلك OCX
هنا «Any CPU فسيُحلّ الأمر» لا ينفع في الغالب. حتّى عند بناء نافذة توافق COM في جانب .NET الجديد، مظهر الشيفرة المُدارة و bitness لـ COM host فعليّاً مشكلتان منفصلتان. البدء بتهاون هنا يُخرج ذلك النوع المزعج: البناء ينجح ولا يعمل عند التوزيع.
flowchart TB
accTitle: ثالوث OCX بـ 32bit والانتقال إلى 64bit
accDescr: لا يمكن تحميل OCX بـ 32bit in-proc في عمليّة 64bit، لذا تسقط الخيارات على الإبقاء على المضيف بـ 32bit، أو حبسه في عمليّة 32bit منفصلة والربط بـ IPC أو COM من نوع out-of-proc، أو الاستبدال من المواضع القابلة للنزع.
wall["OCX بـ 32bit غير ممكن in-proc"] --> o1["الإبقاء على المضيف بـ 32bit"]
wall --> o2["الحبس في عمليّة 32bit منفصلة"]
wall --> o3["الاستبدال من المواضع القابلة للنزع"]
o2 -.-> ipc["الربط بـ IPC أو COM من نوع out-of-proc"]
الشكل 13: حاجز bitness لا يُتجاوز بالعزيمة، والخيارات الواقعيّة تسقط على هذا الثالوث.
4.3. التسجيل والنشر والصلاحيّات والترخيص
يمكن الاستدعاء تقنيّاً، ثمّ يموت المشروع عند النشر. هذا شائع جدّاً مع ActiveX / OCX.
نقاط الصعوبة تميل إلى هذا النطاق.
- افتراض
regsvr32صار معتمداً على الأشخاص - موضع DLL المعتمدة ضمنيّ
- امتيازات المدير لازمة لكنّها لم تسقط في إجراءات التشغيل
- ترخيص design-time / runtime لعناصر تحكّم البائعين منقسم
- يعمل على جهاز التطوير ولا يعمل في بيئة نظيفة
هذه توقف المشروع دون لمس سطر واحد من الشيفرة.
قد يسهّل الأمر ترتيب بلا تسجيل أو نشر side-by-side، لكنّه ليس مسحوقاً سحريّاً. يلزم التحقّق من التوافق مع جانب الحاوية وأسلوب النشر.
بمعنى آخر، ترحيل ActiveX / OCX تصميم نشر أيضاً لا تنفيذاً فقط. تأجيل هذا يسقطكم سقوطاً مدوّياً في النهاية.
flowchart TB
accTitle: نقاط الصعوبة التي توقف النشر
accDescr: اعتماد regsvr32 على الأشخاص، وموضع DLL المعتمدة الضمنيّ، وامتيازات المدير الخارجة عن الإجراءات، والترخيص المنقسم بين design-time و runtime، توقف المشروع دون لمس سطر من الشيفرة.
dist["تصميم النشر"] --> d1["regsvr32 معتمد على الأشخاص"]
dist --> d2["DLL المعتمدة ضمنيّة"]
dist --> d3["امتيازات المدير خارج الإجراءات"]
dist --> d4["الترخيص منقسم"]
d1 -.-> stopx["يتوقّف دون لمس الشيفرة"]
الشكل 14: يمكن الاستدعاء تقنيّاً ثمّ يموت النشر؛ صمّموا نقطة الصعوبة هذه بمعزل عن التنفيذ.
4.4. STA / حلقة الرسائل / الـ callback
ActiveX / OCX ليسا مجرّد استدعاء DLL. قد يحملان افتراضات نموذج خيوط COM وحلقة الرسائل.
ما ينبغي الانتباه إليه خصوصاً حالات كهذه.
- لا يستقرّ إلا بافتراض UI thread
- يُستدعى بتهاون من جانب MTA رغم افتراض STA
- يعود callback أثناء استدعاء متزامن
- افتراض الخيط الذي يستقبل الأحداث مبهم
هذه تظهر أوّلاً بوجه حكاية «يتجمّد أحياناً» أو «الحدث لا يأتي أحياناً». لكن المحتوى في الغالب انتهاك للافتراض.
لذا، سواء عند التغليف أو عند الاستبدال، الأولى تثبيت أيّ خيط يُنشأ عليه، وأيّ خيط يُستدعى منه، وأين يُستقبل الحدث.
flowchart TB
accTitle: تثبيت افتراضات الخيط أوّلاً
accDescr: إن لم يُثبَّت أوّلاً أيّ خيط يُنشأ عليه وأيّ خيط يُستدعى منه وأين يُستقبل الحدث، صارت الحكاية «يتجمّد أحياناً / الحدث لا يأتي أحياناً» انتهاكاً للافتراض.
fix["ثلاث نقاط تُثبَّت أوّلاً"] --> t1["أيّ خيط يُنشأ عليه"]
fix --> t2["أيّ خيط يُستدعى منه"]
fix --> t3["أين يُستقبل الحدث"]
t1 -.-> ghost["الإبهام يحوّلها إلى حكاية انتهاك للافتراض"]
الشكل 15: محتوى «يتجمّد أحياناً» في الغالب انتهاك للافتراض، ويُمنع بتثبيت اتفاق الخيوط أوّلاً.
4.5. هل ثمّة اختبارات، وهل يمكن الرصد
صعوبة الاستبدال ليست لأنّ الشيفرة قديمة فحسب. بل لأنّه لا يوجد ما به يُقال «عمل بالطريقة نفسها».
وجود مثل هذه يكفي ليغيّر الأمر كثيراً.
- اختبار دخان لكلّ سيناريو تشغيل
- عيّنات إدخال وإخراج
- لقطات شاشة أو عيّنات تقارير
- أنماط الأخطاء والسلوك المتوقّع
- سجلات عند المهلة أو عند عدم اتّصال الجهاز
خصوصاً عند ارتباط الأجهزة أو التقارير، يحدث أمر غريب: سلوك الموجود أصدق من المواصفات المكتوبة. من دون وسيلة رصد هنا، يتحوّل الاستبدال إلى تحقيق تنقيبيّ.
flowchart TB
accTitle: وسائل الرصد تسند الاستبدال
accDescr: إن لم توجد وسائل رصد مثل اختبار الدخان وعيّنات الإدخال والإخراج وعيّنات التقارير وأنماط الأخطاء والسلوك المتوقّع، فلا يوجد ما به يُقال إنّه عمل بالطريقة نفسها، ويتحوّل الاستبدال إلى تحقيق تنقيبيّ.
q{"هل ثمّة وسائل رصد"}
q -->|"نعم"| ok["يمكن القول إنّه عمل بالطريقة نفسها"]
q -->|"لا"| dig["الاستبدال يصير تحقيقاً تنقيبيّاً"]
ok -.-> ex["اختبارات دخان وعيّنات وما شابه"]
الشكل 16: صعوبة الاستبدال تُحسم بوجود وسيلة رصد تقول «عمل بالطريقة نفسها» أكثر ممّا تُحسم بقدم الشيفرة.
5. توصيات حسب الأنماط الشائعة
5.1. تطبيق سطح مكتب داخليّ ما يزال مستقرّاً
التوصية: أميل إلى الإبقاء.
في شروط كهذه، غالباً الأفضل ألا تُنزع قسراً.
- يُستخدم داخل المؤسّسة فقط
- الأجهزة المستهدفة ونظام التشغيل ثابتان إلى حدّ ما
- ذلك OCX يُستخدم في شاشات قليلة فقط
- طلبات التعديل صغيرة، والعمر مقروء
غير أنّه لا يُترك عارياً كما هو؛ جمع مواضع الاستدعاء وحدها ينفع لاحقاً.
أي أنّ الاتّجاه هكذا.
- الإبقاء الآن
- لكن ترتيب الحدّ وحده
- جعله شكلاً يمكن البدء منه عندما يصير الاستبدال لازماً
هذا البناء الثلاثيّ هو الأوضح.
5.2. نقل OCX بـ 32bit إلى جانب 64bit
التوصية: تغليف / تغيير البنية.
المواجهة المباشرة هنا تصل إلى طريق مسدود. لأنّ إدخال OCX بـ 32bit in-proc في عمليّة 64bit غير ممكن.
عمليّاً، حبس المكوّن في عمليّة مساعدة 32bit أو جانب LocalServer، والتواصل مع تطبيق 64bit بـ API خشن، ترتيب أسهل في التعامل.
sequenceDiagram
participant App as تطبيق .NET بـ 64bit
participant Bridge as مساعد 32bit / LocalServer
participant Ocx as OCX بـ 32bit
App->>Bridge: طلب بـ API خشن
Bridge->>Ocx: استدعاء in-proc
Ocx-->>Bridge: نتيجة / حدث
Bridge-->>App: نتيجة محوَّلة
الشكل 17: ترتيب يستخدم فيه تطبيق 64bit OCX المحبوس في مساعد 32bit عبر API خشن.
النقطة هنا هي عدم ترحيل الميثودات الدقيقة كلّها كما هي. حدّ ما بين العمليّات يصير شاقاً سريعاً إن تدفّقت فيه استدعاءات دقيقة بكثرة.
- تقريب الوحدة إلى عملية واحدة = طلب واحد تقريباً
- تشكيل قيم الإرجاع والأخطاء بوحدات ذات معنى
- أخذ السجلّ في الحدّ
بهذا الشكل يصير الاستبدال الحقيقيّ للمحتوى لاحقاً أسهل أيضاً.
ما سبق افترض EXE مساعداً خاصّاً بكم، لكن ثمّة خيار جدير بالتحقّق أوّلاً قبل تلك المرحلة.
إن كان ذلك OCX / DLL خادم COM من نوع in-proc، أي يمكن تسجيله بـ InprocServer32، فيمكن وضعه على عمليّة surrogate المرفقة مع Windows وإخراجه كخادم Local Server من نوع out-of-proc.
يكفي إلحاق AppID بـ CLSID وكتابة DllSurrogate فارغ تحت مفتاح ذلك AppID، دون سطر واحد من شيفرتكم.
خطوات التسجيل ملخّصة في القسم 3.5 من فخاخ التسجيل و bitness في تطوير COM/OCX/ActiveX.
غير أنّ الـ surrogate لا يُلغي فرق bitness. ما يزول هو قيْد وجوب التحميل في العمليّة نفسها فقط، ويصير الاستدعاء out-of-proc، وتبقى تكلفة الـ marshaling والاتّصال بين العمليّات كما هي.
الاختيار بينهما يُحسم في الغالب بهذا الجدول.
| الوضع | ما يُختار | السبب |
|---|---|---|
| كائن أتمتة يكتمل باستدعاء الميثودات والأحداث | الـ surrogate أوّلاً | يكفي التسجيل ليصير out-of-proc، ولا شيفرة تُكتب |
الأنواع المتبادلة يمكن marshalingها بـ IDispatch أو proxy / stub مسجّل |
الـ surrogate أوّلاً | علاج عبور الحدّ موجود أصلاً |
ذلك CLSID يحمل أصلاً تسجيل EXE مثل LocalServer32 |
لا دور للـ surrogate | تشغيل خادم EXE أو الخدمة يتقدّم دائماً |
| المراد استخدامه عنصر تحكّم مرئيّاً يُلصق على نموذج ويرسم | التفكير ببنية أخرى | النافذة تفترض وجودها داخل عمليّة المضيف |
| الاستدعاءات الدقيقة متكرّرة، وترحيلها كما هي ثقيل | EXE مساعد خاصّ بكم | تحتاجون طبقة تجمعها في API خشن |
| واجهة خاصّة بلا marshaling | EXE مساعد خاصّ بكم | تجهيز proxy / stub أو تقرير أنواع الحدّ بأنفسكم أسرع |
| المراد الإمساك بترتيب التهيئة وإعادة الاتّصال والمهلة والسجلّ | EXE مساعد خاصّ بكم | عمر عمليّة الـ surrogate متروك لـ COM |
أي أنّ الـ surrogate أصغر يد تستحقّ التجربة أوّلاً، و EXE الخاصّ بكم يد تُستخدم عندما تريدون تصميم الحدّ بأنفسكم. صفّ جدول 3.1 «المراد إدخال OCX بـ 32bit كما هو في عمليّة 64bit ← تغليف / تغيير البنية» لا يتغيّر. اقرأوا أنّ داخل ذلك «التغليف» درجتين.
5.3. شاشات تفترض IE / WebBrowser
التوصية: أولويّة الاستبدال.
هذا مجال يصعب فيه أن يتطابق «يعمل الآن» مع «يسهل إبقاؤه لاحقاً». IE mode يعين كثيراً من أجل التوافق، لكنّ الافتراض يبقى عالم IE.
لذا يسهل الفهم بفصل التفكير هكذا.
- تمديد العمر بـ IE mode كي لا تتوقّف الأعمال الداخليّة
- لكن عدم الخلط بين تمديد العمر والتصميم الدائم
- اختيار وجهة الاستبدال من WebView2 أو ويب خالص أو هجين واجهة أصيلة + ويب
نكتب أيضاً العلاج الملموس في جانب تمديد العمر. IE mode ليس شيئاً «يعمل من تلقاء نفسه بمجرّد تثبيت Edge»؛ المواقع المستهدفة لا تُفتح بمحرّك عالم IE إلا بعد تعيينها بالسياسة. مداخل الضبط ثلاثة.
| الأسلوب | الضبط | ملاحظة |
|---|---|---|
| تعداد المواقع | في نهج المجموعة لـ Microsoft Edge 78 وما بعده، عيّنوا موضع XML لقائمة مواقع وضع المؤسّسة في «Configure the Enterprise Mode Site List» | الشكل الأساسيّ |
| إعادة استخدام قائمة IE القديمة | سياسة Internet Explorer «Use the Enterprise Mode IE website list» | إن وُجدت سياسة جانب Edge فهي تتقدّم |
| تمرير الإنترانت كلّها | تفعيل نهج المجموعة لـ Microsoft Edge 77 وما بعده «Send all intranet sites to Internet Explorer» | النطاق يتّسع، لذا لا يغني عن الجرد |
الافتراض اللازم: تحديثات Windows و Edge محدَّثة، وقوالب إدارة Microsoft Edge مثبَّتة، و Internet Explorer 11 مفعَّل في ميزات Windows. إن نقص أحدها فشل IE mode.
لاحظوا أنّ عناصر تحكّم ActiveX و Browser Helper Object تعمل في IE mode. أي أنّ تمديد العمر ممكن حقّاً. ولهذا تحديداً، الاستمرار بلا شرط إنهاء يجعل الخروج متعذّراً. حديث النزع ملخّص في دليل الخروج من أنظمة تعتمد IE mode.
flowchart TB
accTitle: طريقة التفكير في تمديد العمر بـ IE mode
accDescr: IE mode لا يعمل إلا بعد تعيين المواقع المستهدفة بالسياسة، و ActiveX يعمل أيضاً لذا تمديد العمر ممكن حقّاً، لكن من دون الخلط بين تمديد العمر والتصميم الدائم، واستخدامه بلا شرط إنهاء يجعل الخروج متعذّراً.
policy["تعيين المواقع المستهدفة بالسياسة"] --> iem["الفتح في IE mode"]
iem --> alive["يمكن تمديد العمر بما فيه ActiveX"]
alive --> cond["الاستخدام مع شرط إنهاء"]
cond -.-> exitw["بلا شرط يصير الخروج متعذّراً"]
الشكل 18: تمديد العمر بـ IE mode «يعمل حقّاً»، ولهذا يُستخدم مع شرط إنهاء.
خصوصاً إن استُخدم عنصر تحكّم WebBrowser عارض HTML فحسب،
فأولويّة الاستبدال عالية.
في المقابل، إن كان ActiveX داخل المتصفّح يحمل أيضاً أدوار ملفّات محلّيّة أو أجهزة أو توقيع أو إضافات خاصّة، فذلك ليس استبدال محرّك رسم بل إعادة تصميم الربط الأصيل. الحديث هنا يصير أثقل قليلاً.
5.4. ActiveX يحمل تحكّم أجهزة أو مواصفات خاصّة
التوصية: التغليف أوّلاً.
هذا النوع محتواه كثيف أكثر من مظهره. حتّى إن كانت وثائق SDK رقيقة، قد تكون سلوكات كهذه تراكمت ضمنيّاً نتيجة سنوات من العمل في الميدان.
- طريقة الانتظار عند فشل الاتّصال
- إعادة المحاولة بعد المهلة
- ترتيب الأحداث
- معالجات التجنّب التي تمتصّ عادات الجهاز الحقيقيّ
- تفسير الاستثناءات وأكواد الخطأ
إعادة بناء مكوّن من هذا النوع بحجّة «قديم على أيّ حال» تُشعل في الغالب اختبارات الميدان.
لذا الأأمن البدء من هنا.
- حبس المكوّن القائم داخل الحدّ
- إضافة سجلات لإظهار ما يحدث
- جمع سيناريوهات الاختبار وأنماط الجهاز الحقيقيّ
- بعد ذلك اقتطاع النطاق القابل للاستبدال
لا بريق فيه، لكنّه في العمل اليوميّ الأكثر نفعاً.
flowchart TB
accTitle: طريقة التقدّم مع ActiveX يحمل مواصفات
accDescr: التقدّم بحبس المكوّن القائم داخل الحدّ، ثمّ إضافة سجلات لإظهار ما يحدث، ثمّ جمع السيناريوهات وأنماط الجهاز الحقيقيّ، ثمّ اقتطاع النطاق القابل للاستبدال.
s1["الحبس داخل الحدّ"] --> s2["إضافة سجلات للإظهار"]
s2 --> s3["جمع السيناريوهات وأنماط الجهاز"]
s3 --> s4["اقتطاع النطاق القابل للاستبدال"]
الشكل 19: المكوّن الذي يحمل تحكّم أجهزة أو مواصفات خاصّة يقلّ اشتعال اختبارات الميدان إن تقدّمتم بهذا الترتيب.
6. أنماط مضادّة شائعة
| النمط المضادّ | ما الذي يشقّ | الإصلاح الأوّل |
|---|---|---|
| إعادة كتابة شاملة لأنّ ثمّة ActiveX | سهولة تسرّب المواصفات وانفجار الجهد | الجرد أوّلاً واقتطاع الحدّ |
| محاولة إدخال OCX بـ 32bit كما هو في تطبيق 64bit | مستحيل مبدئيّاً | العزل في جانب 32bit أو تغيير البنية |
| استدعاء API عنصر التحكّم مباشرةً من الشاشات | يسهل أن يصير غير قابل للاستبدال | التقريب إلى adapter / facade |
تشغيل خطوات regsvr32 يدوياً |
حادث في كلّ مرّة باختلاف البيئة | النظر في المثبِّت أو السكربت أو التحويل إلى بيان |
| الاطمئنان لوجود IE mode | سهولة الخلط بين تمديد العمر والمعالجة الدائمة | تقرير خطّة الاستبدال وشرط الإنهاء |
| عدم تسجيل السلوك قبل الاستبدال | تعذّر الحكم بالاكتمال | تجهيز اختبار دخان وبيانات عيّنة وسجلات |
من بينها، الثلاثة الأكثر مشاهدة في العمل اليوميّ هي هذه.
- الاستعجال بإعادة الكتابة الشاملة
- الاستخفاف بحاجز bitness
- بعثرة الـ API في التطبيق كلّه
تجنّب هذه الثلاثة وحدها يخفض معدّل الحوادث كثيراً.
flowchart TB
accTitle: ثلاثة أنماط مضادّة تُشاهد كثيراً خصوصاً
accDescr: تجنّب الاستعجال بإعادة الكتابة الشاملة والاستخفاف بحاجز bitness وبعثرة API عنصر التحكّم في التطبيق كلّه يخفض معدّل الحوادث كثيراً.
a1["الاستعجال بإعادة الكتابة الشاملة"] --> avoid["تجنّب هذه الثلاثة"]
a2["الاستخفاف بحاجز bitness"] --> avoid
a3["بعثرة الـ API في الكلّ"] --> avoid
avoid --> down["ينخفض معدّل الحوادث كثيراً"]
الشكل 20: من بين الأنماط المضادّة، هذه الثلاثة أعلى معدّل لقاء، وتجنّبها وحده ذو أثر كبير.
7. قائمة فحص لبدء الترحيل
مشاريع ActiveX / OCX تنجح أكثر بالجرد أوّلاً بدل الدخول فوراً في التنفيذ. الترتيب في الغالب هكذا.
- استخراج OCX / DLL المستخدمة
- اسم الملفّ، الإصدار، ProgID، CLSID، البائع، وجود الترخيص
- استخراج أين تُستخدم
- الشاشات، الوظائف، التقارير، الأجهزة، الدفعات، ربط Office وغيرها
- التحقّق من bitness وشروط المضيف
- 32bit / 64bit، in-proc / out-of-proc، افتراض STA، اعتماد المتصفّح
- التحقّق من شروط النشر
- طريقة التسجيل، DLL المعتمدة، امتيازات المدير، التثبيت الصامت، إعادة الإنتاج في بيئة نظيفة
- صنع اختبار دخان
- ليس المسار السليم فقط، بل حالات الفشل وعدم الاتّصال والمهلة أيضاً
- بناء حدّ
- adapter، service، facade، جسر عمليّة منفصلة وغيرها
- التجريب بوحدة صغيرة: شاشة واحدة، وظيفة واحدة، جهاز واحد
- من الحدّ الذي نجح، توسيع الإبقاء / التغليف / الاستبدال بالترتيب
تجاوز هذه الخطوات يجعل حتّى شرح «ما الذي كان صعباً» عسيراً لاحقاً.
8. دليل اختيار تقريبيّ
| الوضع | ما يُختار أوّلاً |
|---|---|
| استخدام داخليّ مستقرّ، والتغيير صغير | الإبقاء |
| المراد نقل المحيط فقط إلى .NET | التغليف |
| تصادم 32bit / 64bit | تغليف / تغيير البنية |
| اعتماد IE / WebBrowser / ActiveX المتصفّح | الاستبدال |
| مكوّن واجهة فحسب وثمّة بديل | الاستبدال |
| يحمل تحكّم أجهزة أو تقارير أو مواصفات خاصّة | التغليف |
| يسقط في كلّ مرّة عند التسجيل أو النشر | التغليف أو الاستبدال |
عند الحيرة، تمييز مكوّن واجهة أم سطح حدّ يحمل مواصفات أوّلاً يصعّب الانحراف كثيراً.
9. الخلاصة
كيفية التعامل مع ActiveX / OCX ليست حديث كراهية لأنّه قديم.
النقاط التي تُنظر أوّلاً أربع.
- هل المكوّن مجرّد واجهة، أم سطح حدّ يحمل مواصفات
- هل يلزم استخدامه في العمليّة نفسها
- هل يعلق الأمر عند 32bit / 64bit أو التسجيل أو اعتماد المتصفّح أو الترخيص
- هل يمكن رصد السلوك قبل الاستبدال
إن ظهرت هذه الأربع، أمكن التنظيم في الغالب هكذا.
- إن كان مستقرّاً والعمر مقروءاً، فالإبقاء
- إن كان المراد تحديث المحيط فقط، فالتغليف
- إن كان مكوّن واجهة أو اعتماد متصفّح، فالاستبدال
- إن كان مكوّناً يحمل كتلة مواصفات، فالتغليف أوّلاً ثمّ الاستبدال على مراحل
التقنية القديمة ليست مادة للسخرية، بل موجود يحمل تاريخاً وعقوداً. غير أنّ تصميم الحدّ للتعامل مع ذلك الموجود لازم.
حين تصيرون قادرين على خلط «الإبقاء والتغليف والاستبدال» في التفكير، تتحوّل مشاريع ActiveX / OCX فجأة إلى مشكلات قابلة للمعالجة.
flowchart TB
accTitle: تنظيم الخلاصة
accDescr: إن كان مستقرّاً والعمر مقروءاً فالإبقاء، وإن كان المراد تحديث المحيط فقط فالتغليف، وإن كان مكوّن واجهة أو اعتماد متصفّح فالاستبدال، وإن كان مكوّناً يحمل كتلة مواصفات فالتغليف أوّلاً ثمّ الاستبدال على مراحل.
q["التعامل مع ActiveX / OCX"] --> k["الإبقاء إن كان مستقرّاً"]
q --> w["التغليف إن كان تحديث المحيط"]
q --> r["الاستبدال للواجهة أو اعتماد المتصفّح"]
q --> p["كتلة المواصفات: تغليف ثمّ استبدال مرحليّ"]
الشكل 21: إن ظهرت النقاط الأربع التي تُنظر، أمكن تنظيم الإبقاء والتغليف والاستبدال بهذا الشكل.
10. نوع الاستشارة الذي يلائم هذا الموضوع
هذا الموضوع تخرج قيمته بسهولة حتّى من ترتيب الاتّجاه وحده قبل الدخول في التطوير.
مثلاً، استشارات كهذه ملائمة جدّاً.
- جرد أيّ OCX ينبغي استبداله حقّاً
- ترتيب نقاط تعثّر 32bit / 64bit وحدها أوّلاً
- الانتقال إلى .NET مع الإبقاء على مدخل COM فقط
- مقارنة تمديد العمر وخطة الانسحاب لـ ActiveX انتهى دعم بائعه
- النظر من أين يمكن نزع اعتماد IE / WebBrowser
- فصل شاشة واحدة أو وظيفة واحدة بأمان أوّلاً
مشاريع ActiveX / OCX كثيراً ما يُحسم فيها كيف يُقطع الحدّ قبل التنفيذ. الدخول من ترتيب الوضع القائم ومقارنة البنى وتصميم ترتيب الترحيل، كمرحلة سابقة للتعديل الشامل، له معنى كبير أيضاً.
11. المراجع
- Microsoft Learn, AxHost Class (System.Windows.Forms)
- Microsoft Learn, Aximp.exe (Windows Forms ActiveX Control Importer)
- Microsoft Learn, How to: Add ActiveX Controls to Windows Forms
- Microsoft Learn, Expose .NET Core components to COM
- Microsoft Learn, Registration-Free COM Interop
- Microsoft Learn, DllSurrogate
- Microsoft Learn, Registering the DLL Server for Surrogate Activation
- Microsoft Learn, Microsoft Edge frequently asked questions
- Microsoft Learn, What is Internet Explorer (IE) mode?
- Microsoft Learn, WebBrowser Class (System.Windows.Forms)
- Microsoft Learn, Introduction to Microsoft Edge WebView2
- مدوّنة شركة كومورا سوفت, معرفة أساسيّة لتجنّب التعليق في STA/MTA لـ COM
- مدوّنة شركة كومورا سوفت, لماذا يفضَّل صنع غلاف بـ C++/CLI عند استخدام native DLL من C#
- مدوّنة شركة كومورا سوفت, دراسة حالة يفيد فيها COM: استدعاء DLL بـ 64bit من تطبيق 32bit
- مدوّنة شركة كومورا سوفت, ما هي COM / ActiveX / OCX: الفروق والعلاقات
- مدوّنة شركة كومورا سوفت, استخدام DLL من .NET 8 بأنواع من VBA: كشف COM و dscom TLB
- مدوّنة شركة كومورا سوفت, ما هو Reg-Free COM: استخدام COM بلا تسجيل
- مدوّنة شركة كومورا سوفت, فخاخ التسجيل و bitness في تطوير COM/OCX/ActiveX
- مدوّنة شركة كومورا سوفت, دليل الخروج من أنظمة تعتمد IE mode
- مدوّنة شركة كومورا سوفت, هل WebView2 كافٍ بعد IE mode: قيْد تعطّل ActiveX وتصميم ترحيل واقعيّ
مقالات ذات صلة
أحدث المقالات التي تشترك في نفس الوسوم. عمّق فهمك بمواضيع مرتبطة.
ما ينبغي تنظيمه قبل طلب التعهيد أو التطوير التعاقديّ لتطبيق Windows
قبل تكليف جهة خارجية بتطوير تطبيق Windows تعاقديّاً، إليك النقاط التي ينبغي تنظيمها: تعديل البرمجيّات القائمة، وتكامل الأجهزة، وCOM/Activ...
فخاخ التسجيل وbitness في تطوير COM و OCX / ActiveX
نرتّب من منظور عمليّ ما يسهل التعثّر فيه في تطوير COM و OCX و ActiveX: 32-bit/64-bit، Visual Studio 2022، regsvr32/Regasm، صلاحيات المسؤو...
ما هي COM / ActiveX / OCX: الفروق والعلاقات
تنظيم ما هي COM وما هي ActiveX وما هي OCX، مع الفروق والعلاقات وصلة OLE، وأين تُستخدم، وكيف تُفهم اليوم من منظور العمل اليومي.
هل تعمل تطبيقات الأعمال على Windows بإصدار Arm؟ ── واقع محاكاة x64 (Prism) ومكتبات DLL وCOM الأصليّة
نجيب المطوّرين ومسؤولي الأنظمة عن سؤال «هل تعمل تطبيقات الأعمال على Windows بإصدار Arm؟». نستعرض آليّة محاكاة x64 (Prism)، والطبقات التي ...
قائمة التحقّق قبل ترحيل .NET Framework إلى .NET
قائمة تحقّق عمليّة قبل ترحيل .NET Framework إلى .NET: نوع المشروع، والتقنيات غير المدعومة، وتبعيّات NuGet، وأسلوب SDK، و WPF/WinForms، و ...
أين يتصل هذا الموضوع
ترتبط هذه المقالة بشكل طبيعي بصفحات الخدمات التالية.
دعم إعادة استخدام الأصول القديمة وترحيلها
قرار الإبقاء على COM / ActiveX / OCX أو تغليفها أو استبدالها هو بعينه الموضوع المحوري لدعم إعادة استخدام الأصول القديمة وترحيلها.
الاستشارات التقنية ومراجعة التصميم
إذا كنتم في مرحلة تريدون فيها ترتيب الحدود وتحديد ترتيب الاستبدال قبل التنفيذ، فإنّ بلورة الخطّة ضمن الاستشارة التقنيّة ومراجعة التصميم أسلوب مناسب.
الأسئلة الشائعة
أسئلة شائعة حول موضوع هذه المقالة.
- هل ينبغي استبدال ActiveX / OCX؟
- لا يُحكم بالقدم، بل بما يتحمّله المكوّن فعلاً. إن كان مجرّد مكوّن واجهة وله بديل فالاستبدال مناسب، وإن كان يحمل تحكّم أجهزة أو تقارير أو صيغة ملفّ خاصّة فغلّفه أوّلاً وثبّت الحدّ، وإن كان مستقرّاً ونطاق التغيير صغيراً فقرار الإبقاء واقعيّ أيضاً. «إعادة الكتابة الشاملة كيفما اتّفق» و«التجميد الدائم لأنّ الأمر مخيف» خياران مرتفعا معدّل الحوادث.
- هل يمكن استخدام OCX بـ 32bit من تطبيق 64bit؟
- لا in-proc. يجب أن يطابق OCX bitness العمليّة التي تحمّله، وهذا قيْد مبدئيّ. الخيارات الواقعيّة ثلاثة: الإبقاء مؤقّتاً على تطبيق المضيف بـ 32bit أيضاً، أو حبسه في عمليّة 32bit منفصلة (EXE مساعد أو COM LocalServer) والربط بجانب 64bit عبر IPC أو COM من نوع out-of-proc، أو البدء بالاستبدال من المواضع التي يمكن فيها نزع الاعتماد على ذلك OCX.
- ماذا نفعل باعتماد ActiveX في المتصفّح؟
- الأفضل النظر إليه بأولويّة الاستبدال. Microsoft Edge نفسه لا يدعم ActiveX، و IE mode موضوع في موقع تمديد العمر فقط. عنصر تحكّم WebBrowser يجرّ كذلك عالم IE، فإذا كان المراد عرض HTML فحسب فـ WebView2 هو المرشّح الأوّل. غير أن WebView2 ليس مكوّن استبدال كاملاً: السكربتات التي تفترض IE DOM والافتراضات حول window.external لا تنتقل كما هي.
- ماذا يعني عمليّاً «تغليف» ActiveX / OCX؟
- حبس ActiveX / OCX داخل حدّ ضيّق، وإظهاره للمحيط كـ API جديد أو مكوّن شاشة. الأنماط تشمل مضيفاً في WinForms مع AxHost، وجسراً إلى عمليّة منفصلة بـ EXE مساعد 32bit أو LocalServer، ونافذة توافق COM في جانب .NET. عند التغليف لا تُنسخ الـ API القديمة بالجملة؛ تُحوَّل إلى ميثودات بوحدات خشنة، ويُحدَّد في الحدّ مسؤوليّة السجلّ والمهلة وتحويل الاستثناءات، ويُبنى الشكل بحيث يمكن استبدال الوجهة المستقبليّة بالواجهة نفسها.
الملف الشخصي للمؤلف
صفحة الملف الشخصي لمؤلف المقالة.
غو كومورا
مؤسّس شركة كومورا سوفت ذ.م.م.
يركّز على تطوير برامج ويندوز، والاستشارات التقنية، والتحقيق في الأخطاء، ويتميّز في المشاريع التي تبقى فيها الأصول القديمة ناشطة، وفي تشخيص الأعطال التي يصعب تحديد سببها.