تكامل صدفة ويندوز اليوم ── قوائم السياق وارتباطات الملف وما تغيّر في ويندوز 11

· · Windows, امتدادات الصدفة, قائمة السياق, ارتباط الملف, COM, Windows 11, مستكشف الملفّات, MSIX, تطوير ويندوز

استُشرتُ بـ«استبدلنا الحواسيب بويندوز 11، واختفت قائمة سياق التطبيق الذي بنيتموه لنا قبل سنوات». بالاستماع بدقّة أكبر، لم تختفِ. انقر ملفّاً باليمين، واختر «إظهار المزيد من الخيارات» أسفل القائمة، فتظهر القائمة المألوفة كما كانت دائماً. أي أنّ عناصر قائمة التطبيق الداخلي أُخفيت نقرةً أبعد. من الميدان نسمع «نقرة إضافيّة واحدة» و«زادت الاستفسارات أنّهم لا يجدون العنصر».

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

في الوقت نفسه، آليّة ارتباط الملف وامتداد الصدفة من تحت ما زالت عالم COM والسجلّ القديم. مفتاح امتداد يشير إلى ProgID، وفعل الـ ProgID يحمل سطر أوامر، وامتداد أكثر تعقيداً يعمل كخادم COM داخل العمليّة (DLL) يُحمَّل في المستكشف — هذا الهيكل لم يتغيّر منذ أكثر من عشرين سنة. إن لم تعرف الأساس الذي لم يتغيّر والقائمة التي شطرها ويندوز 11 شطرين، فلن تستطيع عزل «القائمة لا تظهر» أو «أُخفيت» أو «تظهر مرّتين».

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

1. الخلاصة أوّلاً

  • أساس قائمة السياق وارتباط الملف هو البنية الثلاثيّة للسجلّ «مفتاح الامتداد → ProgID → الفعل». مفتاح الامتداد مؤشّر إلى ProgID، والـ ProgID هو الجوهر، وshell\<verb>\command تحته يحمل سطر الأوامر.1
  • HKEY_CLASSES_ROOT (HKCR) ليست خليّة مستقلّة؛ إنّها عرض مدمج لـ HKLM\Software\Classes وHKCU\Software\Classes. اكتب تسجيل كلّ المستخدمين إلى HKLM وتسجيل كلّ مستخدم إلى HKCU، وعامل HKCR للقراءة فقط.2
  • التطبيق الافتراضي (الذي يُفتَح بالنقر المزدوج) مصمَّم ليختاره المستخدم، ولا يستطيع برنامج سرقته. يحمي نظام التشغيل اختيار المستخدم؛ ما يستطيع المثبِّت فعله هو التسجيل كمرشَّح.3
  • امتداد الصدفة الكلاسيكي DLL COM داخل العمليّة يُحمَّل في المستكشف. انهيار أو تأخير في الامتداد ينتشر إلى المستكشف بأكمله (وإلى تطبيقات أخرى تستخدم الصدفة)؛ بيئة 64 بت تتطلّب DLL بـ 64 بت؛ والتنفيذ بالشيفرة المُدارة غير مدعوم.45
  • في ويندوز 11 انشطرت قائمة السياق شطرين. الأوامر الوحيدة التي تظهر في القائمة الجديدة هي المسجَّلة بـ IExplorerCommand مع هويّة حزمة؛ امتدادات IContextMenu الكلاسيكيّة تُنقَل إلى القائمة القديمة تحت «إظهار المزيد من الخيارات» (Shift+F10).67
  • المسار الرسمي لوضع أمر مخصّص في القائمة الجديدة هو تسجيل DLL أصلي ينفّذ IExplorerCommand في بيان MSIX (desktop4:FileExplorerContextMenus). تطبيق لا يستطيع أن يصير MSIX يمكن منحه الهويّة وحدها بحزمة متفرّقة (MSIX بموقع خارجي).78
  • إن كان كلّ ما تريده هو «الفتح بهذا التطبيق»، فما زال الارتباط وفعل ثابت كافيين. لا تحتاج DLL امتداد صدفة، ومايكروسوفت نفسها تقول بوضوح «اختر أبسط طريقة تلبي المتطلّبات (فعلاً ثابتاً)».9
  • بعد التسجيل أو التغيير، أعلِم بـ SHChangeNotify(SHCNE_ASSOCCHANGED)؛ عند إلغاء التثبيت احذف الـ ProgID لكن لا تحذف القيمة الافتراضيّة لمفتاح الامتداد — هذا الدليل الرسمي. تكامل الصدفة يشمل تصميم التنظيف.110

بجملة واحدة: عالم الارتباطات والأفعال لم يتغيّر؛ وحده كيف تُعرَض القائمة انشطر شطرين في ويندوز 11. أدناه نسير من الأساس صعوداً.

2. كيف يعمل ارتباط الملف ── البنية الثلاثيّة مفتاح الامتداد → ProgID → الفعل

2.1. قراءة البنية الثلاثيّة من مثال واحد

ما يحدث عند النقر المزدوج على ملف بامتداد معيّن تقرّره ثلاث طبقات من مفاتيح السجلّ.1

HKEY_CLASSES_ROOT
   .kmrpt                                  ← (1) مفتاح الامتداد
      (Default) = KomuraSoft.Report.1      ←     مؤشّر يسمّي الـ ProgID فقط
      OpenWithProgids
         KomuraSoft.Report.1               ←     مرشَّح تحت «فتح بواسطة»
   KomuraSoft.Report.1                     ← (2) ProgID (جوهر الارتباط)
      (Default) = Komura Report document
      DefaultIcon
         (Default) = "C:\Program Files\KomuraSoft\Report.exe",0
      shell                                ← (3) قائمة الأفعال
         open
            command
               (Default) = "C:\Program Files\KomuraSoft\Report.exe" "%1"
  • (1) مفتاح الامتداد (.kmrpt) يشير فقط إلى اسم ProgID كقيمته الافتراضيّة. كتابة أمر هنا مباشرة خطأ.
  • (2) الـ ProgID (KomuraSoft.Report.1) هو جوهر الارتباط؛ يحمل اسم العرض والأيقونة وقائمة الأفعال.
  • (3) الفعل عمل مثل «فتح» أو «طباعة»، والقيمة الافتراضيّة لـ shell\open\command هي سطر الأوامر الذي يُطلَق فعلاً.

هذا الفصل هو سبب أن تستطيع توجيه عدّة امتدادات (.kmrpt و.kmrpt-file مثلاً) إلى نفس الـ ProgID، أو استبدال الـ ProgID عند ترقية التطبيق.

البنية الثلاثيّة لارتباط الملفمفتاح الامتداد مؤشّر قيمته الافتراضيّة تسمّي ProgID؛ الـ ProgID هو الجوهر الذي يحمل اسم العرض والأيقونة وقائمة الأفعال؛ والقيمة الافتراضيّة لـ command تحت الفعل هي سطر الأوامر الذي يُطلَق فعلاًيسمّي الـ ProgID افتراضيّاًمفتاح الامتداد .kmrptProgID KomuraSoft.Report.1الفعل (open وغيره تحت shell)القيمة الافتراضيّة لـ commandيُطلَق Report.exeيحمل أيضاً اسم العرض وDefaultIcon

الشكل 1: مفتاح الامتداد مؤشّر، والـ ProgID هو الجوهر، وcommand الفعل هو سطر الأوامر الذي يُطلَق فعلاً.

2.2. HKCR «عرض مدمج» ── أين تكتب يغيّر المعنى

المثال أعلاه معروض تحت HKEY_CLASSES_ROOT (HKCR)، لكن HKCR ليست موقع تخزين مادّي؛ إنّها عرض مدمج لـ HKLM\Software\Classes وHKCU\Software\Classes. إن وُجد نفس المفتاح في الاثنين، جانب HKCU يفوز.2

HKCR عرض مدمجHKCR هي Classes في HKLM وHKCU موضوعتان فوق بعضهما؛ إن وُجد نفس المفتاح في الاثنين تفوز HKCU؛ اكتب التسجيل إلى HKLM أو HKCU صراحة وعامل HKCR للقراءة فقطHKLM\\Software\\Classes (كلّ المستخدمين)HKCR (عرض مدمج)HKCU\\Software\\Classes (لكلّ مستخدم)إن وُجد نفس المفتاح تفوز HKCUعاملها للقراءة فقط (للتأكيد)

الشكل 2: HKCR هي كيف تبدو Classes في HKLM وHKCU معاً؛ سمِّ دائماً أحدهما وجهة الكتابة.

وجهة الكتابة المعنى الحقوق المطلوبة
HKLM\Software\Classes تسجيل مشترك لكلّ المستخدمين مسؤول
HKCU\Software\Classes تسجيل لذلك المستخدم فقط لا شيء
الكتابة إلى HKCR مباشرة تُوزَّع بحسب أين يعيش المفتاح القائم أصلاً يعتمد

عمليّاً، التقسيم الآمن هو دائماً كتابة التسجيل إلى HKLM أو HKCU صراحة، ومعاملة HKCR للقراءة فقط (للتأكيد). العلاقة مع إعادة توجيه سجلّ WOW64 تستحقّ أيضاً الترتيب. بيانات الارتباط مباشرة تحت HKLM\Software\Classes مثل مفاتيح الامتداد والـ ProgID مشتركة بين عرضي السجلّ 32 بت و64 بت منذ ويندوز 7، فمثبِّت 32 بت يكتبها لا يهرب إلى جانب Wow6432Node. بعض مفاتيح COM الفرعيّة مثل Classes\CLSID، من الجهة الأخرى، تُعاد توجيهها، وعند تسجيل امتداد صدفة (COM داخل العمليّة) يهمّ تقسيم الكتابة 32 بت / 64 بت. التفاصيل في “مطبات إعادة توجيه السجلّ 32 بت/64 بت والافتراضيّة — Wow6432Node ومشكلة «القيمة التي كتبتها ليست هناك»”.

2.3. التسجيل في جانب التطبيق ── App Paths وApplications وRegisteredApplications

هناك أيضاً ثلاثة أنواع من التسجيل في جانب التطبيق، تزاوج جانب الملف (الامتداد والـ ProgID).11

  • App Paths (HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths): تسجيل يتيح لـ ShellExecuteEx الإطلاق باسم الملف التنفيذي وحده. توصي مايكروسوفت بهذا لأنّك لا تلوّث متغيّر بيئة PATH.
  • Applications (HKCR\Applications\<app.exe>): يعرّف طريقة الفتح الافتراضيّة عندما يُسلَّم ملف اعتباطي تحت «فتح بواسطة»، واسم عرض التطبيق (FriendlyAppName).
  • RegisteredApplications + Capabilities: يعلن الامتدادات وأنواع MIME التي يستطيع التطبيق معالجتها، وهو التسجيل الذي يجعله يظهر مرشَّحاً في صفحة إعدادات التطبيقات الافتراضيّة في ويندوز.

معظم استشارات «تطبيقنا لا يظهر في قائمة التطبيقات الافتراضيّة» حالات سُجِّل فيها الـ ProgID وأُهمِل تسجيل Capabilities هذا.

أنواع التسجيل الثلاثة في جانب التطبيقتسجيل جانب التطبيق ثلاثة أنواع ── App Paths وApplications وRegisteredApplications ── مسؤولة على التوالي عن الإطلاق باسم الملف وحده، وطريقة الفتح الافتراضيّة تحت فتح بواسطة، والظهور في صفحة التطبيقات الافتراضيّةتسجيل جانب التطبيقApp PathsApplicationsRegisteredApplicationsإطلاق باسم الملف وحدهالافتراضي تحت فتح بواسطةيظهر في صفحة التطبيقات الافتراضيّةيلزم إعلان Capabilities

الشكل 3: هناك ثلاثة أنواع لتسجيل جانب التطبيق، والظهور مرشَّحاً للتطبيقات الافتراضيّة يتطلّب تسجيل Capabilities.

2.4. التطبيق الافتراضي ملك المستخدم ── حماية UserChoice

كتابة ProgID كقيمة افتراضيّة لمفتاح الامتداد لا تجعله وحده التطبيق الافتراضي. نتيجة اختيار المستخدم صراحة تحت «فتح بواسطة» وما شابه تُحفَظ في HKCU\...\Explorer\FileExts\<extension>\UserChoice، وحلّ الارتباط يفضّل ذلك الجانب.

والنقطة المهمّة أنّ ويندوز لا يدعم تغيير التطبيق الافتراضي برمجيّاً. إعدادات التطبيق الافتراضي مصمَّمة لتتمّ عبر واجهة إعدادات النظام بيد المستخدم؛ بيانات UserChoice مشوَّشة، وبرنامج تشغيل ترشيح (UCPD.sys) يحجب الكتابة من التطبيقات. في بيئة مُدارة، سياسة المجموعة / MDM هي الوسيلة الرسميّة.3

أنّ أدواتاً مثل SetUserFTA، التي «تقلّد التجزئة وتعيد الكتابة»، قد استُخدِمت هو الوجه الآخر لهذه الحماية. ما ينبغي وضعه في مثبِّت تطبيق داخلي ليس سرقة الافتراضي، بل الثلاثة: (أ) تسجيل صحيح للـ ProgID والأفعال، (ب) إضافة نفسك إلى OpenWithProgIds، و(ج) إن لزم، التوجيه إلى صفحة الإعدادات.

حلّ التطبيق الافتراضي وحماية UserChoiceنتيجة اختيار المستخدم الصريح تُحفَظ في UserChoice وتُفضَّل في حلّ الارتباط؛ UCPD.sys يحجب إعادة الكتابة من التطبيقات، لذا ما يستطيع المثبِّت فعله هو التسجيل كمرشَّح والتوجيه إلى صفحة الإعداداتمفضَّلUCPD.sys يحجبهاUserChoice (اختيار المستخدم)حلّ الارتباطالقيمة الافتراضيّة لمفتاح الامتدادإعادة كتابة من تطبيقعمل المثبِّتتسجيل الـ ProgID والأفعالالإضافة إلى OpenWithProgIdsالتوجيه إلى صفحة الإعدادات

الشكل 4: حلّ الارتباط يفضّل اختيار المستخدم (UserChoice)، ونظام التشغيل يحميه من إعادة كتابة التطبيقات.

3. أفعال غير «فتح» ── print وedit وrunas وأفعال مخصّصة

الفعل ليس open فقط. الأفعال القياسيّة التي يعرف نظام التشغيل معناها تشمل edit وprint وplay وpreview فضلاً عن open، والفعل القياسي يحصل تلقائيّاً على اسم عرض يتبع لغة نظام التشغيل. الفعل الافتراضي المستخدم عند النقر المزدوج يُقرَّر بالترتيب: القيمة الافتراضيّة لمفتاح shell → أوّل فعل في السجلّ → openopenwith.12

ترتيب تقرير الفعل الافتراضيالفعل الافتراضي المستخدم عند النقر المزدوج هو أوّل ما يُوجَد بترتيب القيمة الافتراضيّة لمفتاح shell ثمّ أوّل فعل في السجلّ ثمّ open ثمّ openwithإن عُدِمإن عُدِمإن عُدِمالقيمة الافتراضيّة لمفتاح shellأوّل فعل في السجلّopenopenwith

الشكل 5: الفعل الافتراضي عند النقر المزدوج هو أوّل ما يُوجَد بهذا الترتيب.

عندما تريد إضافة عملك الخاص، سجّل فعلاً مخصّصاً.

KomuraSoft.Report.1
   shell
      open
         command
            (Default) = "C:\Program Files\KomuraSoft\Report.exe" "%1"
      print
         command
            (Default) = "C:\Program Files\KomuraSoft\Report.exe" /print "%1"
      verify                          ← فعل مخصّص
         (Default) = Verify report (&V)   ← اسم العرض في القائمة
         command
            (Default) = "C:\Program Files\KomuraSoft\Report.exe" /verify "%1"

ثلاث حقائق صغيرة يفيد معرفتها.

  • سجّل فعلاً اسمه runas فتعرّف إطلاقاً برفع الامتياز يعادل «تشغيل كمسؤول»، ويُستخدَم أيضاً عندما تحدّد واجهة ShellExecute القيمة runas.
  • ضع قيمة فارغة اسمها Extended على مفتاح الفعل فيصير فعلاً موسَّعاً يُعرَض فقط عند Shift+نقر أيمن. مناسب لإخفاء عمليّة خطرة نادراً ما تُستخدَم.12
  • بعض ارتباطات التطبيقات الأقدم ما زالت لديها إعداد يرسل مستنداً إلى عمليّة قائمة بـ DDE (مفتاح ddeexec)، لكن إطلاق فعل عبر DDE صار إرثاً Deprecated. لا سبب لكتابته جديداً.12

حادث آخر يحدث كثيراً هو الاقتباس في سطر الأوامر. إن أمكن أن يحتوي عنصر من سلسلة الأمر مسافة، فعليك لفه بعلامات اقتباس. ينطبق ذلك طبعاً على مسار EXE مثل C:\Program Files\...، و%1 (مسار الملف المحدَّد) ينبغي دائماً كتابته "%1". لا تستطيع ضمان أنّ مسار ملف المستخدم لا يحتوي مسافة. My Program.exe بلا اقتباس يُفسَّر كـ«أطلق My بالوسيط Program.exe».13

حادث الاقتباس في سطر الأوامرأمر بلا اقتباس يُقسَم عند المسافة ويُساء تفسيره كأنّه يطلق My بوسيط Program.exe، لذا مسار EXE الذي قد يحتوي مسافة و%1 الذي يمثّل مسار الملف المحدَّد ينبغي دائماً لفهما بعلامات اقتباسيُقسَم عند المسافةأمر بلا اقتباسيُساء تفسيره كإطلاق EXE آخرأمر مقتبسيُطلَق كما قُصِدلف مسار EXE بعلامات اقتباسلف %1 بعلامات اقتباس دائماً أيضاً

الشكل 6: أمر بلا اقتباس يُقسَم خطأ عند مسافة، لذا لف دائماً مسار EXE و%1 بعلامات اقتباس.

آليّة السجلّ وحدها حتى الآن (فعل ثابت) يمكن تحقيقها دون كتابة أي DLL، ولا تخاطر بجعل المستكشف غير مستقر. مايكروسوفت نفسها تكرّر «قبل أن تكتب امتداد صدفة، انظر هل يكفي أبسط فعل ثابت يلبي المتطلّبات».9

4. امتدادات الصدفة الكلاسيكيّة ── DLL يعمل داخل المستكشف

4.1. أنواع امتداد الصدفة

متطلّبات لا يلبيها فعل ثابت — «غيّر القائمة ديناميكيّاً بحسب التحديد»، «استبدل الأيقونة أو ورقة الخصائص» — تستخدم معالج امتداد صدفة. الأنواع التمثيليّة كالتالي.4

المعالج الواجهة الرئيسة ما يستطيع فعله
معالج قائمة السياق IContextMenu + IShellExtInit إضافة عناصر القائمة والتحكّم بها ديناميكيّاً
معالج أيقونة / طبقة أيقونة IExtractIcon / IShellIconOverlayIdentifier أيقونة لكلّ ملف والطبقة
معالج ورقة خصائص IShellPropSheetExt إضافة تبويب إلى ورقة الخصائص
صورة مصغّرة / تلميح معلومات IThumbnailProvider / IQueryInfo عرض الصورة المصغّرة ووصف التحويم
سحب وإفلات / معالج خطاف النسخ IDropTarget / ICopyHook التدخّل عند الإفلات أو النسخ/النقل

هذه كلّها تُنفَّذ كفئات COM وتُسجَّل في السجلّ بـ CLSID. فكرة COM نفسها مشروحة في “ما هي COM / ActiveX / OCX - دليل عمليّ للفروق والعلاقات بينها”.

4.2. ماذا يعني أن تكون خادم COM داخل العمليّة

جوهر امتداد الصدفة الكلاسيكي أنّه خادم COM داخل العمليّة (DLL) يُحمَّل في المستكشف (أو في أي تطبيق فتح حوار ملف شائع). كلّ تحفّظ يتبع من ذلك.4

  • إن انهار الامتداد، يُسقَط المستكشف معه. إن تجمّد، يتجمّد النقر الأيمن ثواني. الضرر أيضاً لا يقتصر على المستكشف؛ يصل إلى كلّ تطبيق عرض حوار فتح ملف.
  • بناء القائمة يحدث على خيط واجهة المستخدم، لذا يجب ألّا تعمل عملاً بطيئاً مثل الوصول إلى الشبكة أو إدخال/إخراج الملف عند عرض القائمة.
  • سجّل نموذج الخيوط Apartment كقاعدة.
بنية الضرر الجانبي لامتداد داخل العمليّةDLL امتداد الصدفة يُحمَّل لا في المستكشف فحسب بل أيضاً في عمليّة أي تطبيق فتح حوار ملف، لذا انهيار أو تجمّد في الامتداد ينتشر إلى العمليّة المضيفة بأكملهايُحمَّل داخل العمليّةيُحمَّل داخل العمليّةDLL امتداد الصدفةالمستكشفأي تطبيق يفتح حواراًانهيار أو تجمّد ينتشرلا تعمل عملاً بطيئاً عند العرض

الشكل 7: DLL الامتداد يعمل داخل العمليّة المضيفة، لذا ينتشر الانهيار أو التجمّد إلى المضيف بأكمله.

حقّق في استشارة مثل «يتجمّد المستكشف عندما أفتح مجلداً معيّناً» أو «النقر الأيمن يستغرق خمس ثوانٍ» وليس نادراً أن يكون السبب امتداد صدفة لطرف ثالث لا التطبيق الداخلي. طرق العزل في الفصل 8.

4.3. مطابقة العرض البتّي ── بيئة 64 بت تتطلّب DLL بـ 64 بت

DLL داخل العمليّة يجب أن يطابق العرض البتّي للعمليّة التي تحمّله. مستكشف ويندوز 64 بت عمليّة 64 بت، لذا DLL امتداد صدفة مبني كـ 32 بت فقط لا يُحمَّل أبداً ولا يظهر في القائمة أصلاً. ولا خطأ أيضاً، لذا هو سبب أساسي لـ«سجّلته لكنّه لا يظهر». الجمع بين جسم تطبيق 32 بت وDLL امتداد صدفة 64 بت تكوين مشروع، لكن عليك مراقبة أنّ تسجيل COM ينقسم حسب العرض البتّي (Wow6432Node). الإطلاق من command الفعل EXE بعمليّة منفصلة، لذا لا يخضع لهذا القيد (تركه EXE بـ 32 بت مقبول).

مطابقة العرض البتّي لـ DLL امتداد الصدفةDLL امتداد الصدفة الوحيد الذي يستطيع مستكشف 64 بت تحميله هو ذو 64 بت؛ DLL بـ 32 بت فقط لا يظهر في القائمة ولا ينتج خطأ؛ EXE يُطلَق من أمر فعل عمليّة منفصلة ولا يخضع للقيديستطيع التحميللا يستطيع التحميلعمليّة منفصلةمستكشف 64 بتDLL امتداد صدفة 64 بتDLL بـ 32 بت فقطلا يظهر في القائمة، بلا خطأEXE يُطلَق من فعلمقبول بقاؤه 32 بت

الشكل 8: DLL الوحيد المحمَّل في مستكشف 64 بت هو DLL بـ 64 بت؛ EXE يُطلَق من فعل لا يخضع لهذا القيد.

4.4. لماذا يجب ألّا تكتبه بشيفرة مُدارة

كثيراً ما يُطرَح السؤال «هل أستطيع كتابة امتداد صدفة بـ C#»، لكن مايكروسوفت صرّحت بوضوح أنّ كتابة امتداد صدفة داخل العمليّة بشيفرة مُدارة (.NET) غير مستحسَنة وخارج الدعم.5

السبب طبيعة تحميل الامتداد في عمليّة اعتباطيّة. اصطدامات إصدار CLR (خصوصاً تحت .NET Framework 4)، ومشكلة إعادة دخول CLR حلقة الرسائل أثناء انتظار قفل، وعمر الكائن غير الحتمي من جمع القمامة وهو يصطدم بعقد عدد المراجع في COM أسباب هيكليّة تجعل التطبيق المضيف غير مستقر. بعض البنود خُفِّفت في .NET Framework 4 وما بعدها وفي .NET الحديث، لكن الموقف الرسمي لم يتغيّر.

المبدأ العملي بسيط. اكتب امتداداً داخل العمليّة بـ C++ أصلي. إن أردت استخدام شيفرة مُدارة، فاجعله EXE عاديّاً يُطلَق من أمر الفعل، أو امتداداً خارج العمليّة يعمل في عمليّة منفصلة (معالج معاينة وما شابه).5

الحكم هل الشيفرة المُدارة مسموحةامتداد داخل العمليّة يعمل داخل المستكشف يُكتَب بـ C++ أصلي كقاعدة؛ إن أردت شيفرة مُدارة فاجعله EXE عاديّاً يُطلَق من أمر فعل أو امتداداً خارج العمليّة يعمل في عمليّة منفصلةنعملايعمل داخل العمليّة؟اكتبه بـ C++ أصليالشيفرة المُدارة مقبولةخطر CLR / إعادة الدخول يجعل المضيف غير مستقرEXE يُطلَق من فعلمعاينة خارج العمليّة

الشكل 9: امتداد داخل العمليّة C++ أصلي كقاعدة؛ الشيفرة المُدارة مقصورة على تكوين يعمل في عمليّة منفصلة.

5. قائمة سياق ويندوز 11 الجديدة ── القائمة المنشطة شطرين

5.1. ماذا حدث

جدّد ويندوز 11 قائمة سياق مستكشف الملفّات. صارت القصّ والنسخ وما شابه صفّ أيقونات في الأعلى؛ و«فتح» و«فتح بواسطة» جُمِعتا في الأعلى؛ والأوامر التي يضيفها تطبيق تُجمَع تحت أوامر الصدفة القياسيّة. عندما يضيف تطبيق واحد عدّة أوامر، تُجمَع في قائمة طائرة (قائمة فرعيّة) باسم التطبيق.6

والنقطة الحاسمة هذه. امتدادات الصدفة المعتمدة على IContextMenu الكلاسيكي لم تُحذَف؛ نُقِلت إلى جانب القائمة القديمة التي تُفتَح بـ«إظهار المزيد من الخيارات» (Shift+F10) وتحمّل قائمة ويندوز 10 كما هي.6 هويّة استشارة الافتتاح «أُخفيت القائمة» هي هذا الانشطار.

قائمة السياق التي شطرها ويندوز 11 شطرينما يُفتَح أوّلاً عند النقر الأيمن هو القائمة الجديدة؛ الأوامر الوحيدة التي تظهر هناك هي المسجَّلة بـ IExplorerCommand وهويّة حزمة؛ امتدادات IContextMenu الكلاسيكيّة تُنقَل إلى القائمة القديمة التي تُفتَح بإظهار المزيد من الخياراتإظهار المزيد Shift+F10نقر أيمن على ملفالقائمة الجديدة (ويندوز 11)أوامر IExplorerCommand + الهويّةالقائمة القديمة (قائمة ويندوز 10)امتدادات IContextMenu الكلاسيكيّةعدّة أوامر تُجمَع في قائمة طائرة

الشكل 10: الأوامر الوحيدة التي تظهر في القائمة الجديدة هي أوامر IExplorerCommand + الهويّة؛ الامتدادات الكلاسيكيّة تُنقَل إلى جانب القائمة القديمة.

5.2. المسار الرسمي إلى القائمة الجديدة ── IExplorerCommand + تسجيل البيان

هناك طريقة واحدة لوضع أمر مخصّص في القائمة الجديدة. جهّز DLL أصليّاً ينفّذ واجهة IExplorerCommand، وأعلن خادم COM وامتداد قائمة السياق في بيان حزمة MSIX.7

<!-- Package manifest (excerpt) -->
<com:Extension Category="windows.comServer">
  <com:ComServer>
    <com:SurrogateServer DisplayName="Komura commands">
      <com:Class Id="01234567-89AB-CDEF-0123-456789ABCDEF"
                 Path="KomuraCommand.dll" ThreadingModel="STA" />
    </com:SurrogateServer>
  </com:ComServer>
</com:Extension>
<desktop4:Extension Category="windows.fileExplorerContextMenus">
  <desktop4:FileExplorerContextMenus>
    <desktop5:ItemType Type=".kmrpt">
      <desktop5:Verb Id="VerifyReport"
                     Clsid="01234567-89AB-CDEF-0123-456789ABCDEF" />
    </desktop5:ItemType>
  </desktop4:FileExplorerContextMenus>
</desktop4:Extension>

Type في ItemType يستطيع تحديد امتداد معيّن، أو * (كلّ الملفّات)، أو Directory (المجلدات)، أو Directory\Background (خلفيّة مجلد). طابق الـ DLL مع معمارية المستكشف (64 بت / ARM64).7

IExplorerCommand نفسها واجهة موجودة منذ حقبة ويندوز 7؛ تنفّذ العنوان (GetTitle) والأيقونة (GetIcon) وحالة التمكين / التعطيل / الإخفاء (GetState) والتنفيذ (Invoke). تُستدعى الطرائق من خيط واجهة المستخدم، لذا الوصول إلى موارد الشبكة ممنوع، وطرائق بناء القائمة تحتاج أن تعود بسرعة. اعمل العمل الثقيل بعد Invoke.147

بنية بيان تسجيل القائمة الجديدةإعلان خادم COM في بيان MSIX يربط CLSID بـ DLL، وإعلان امتداد قائمة السياق يربط الهدف والتنفيذ بـ ItemType وVerb، فيظهر أمر مخصّص في القائمة الجديدةيربط CLSID بـ DLLيحدّد بـ ItemType وVerbبيان MSIXإعلان خادم COMإعلان امتداد القائمةDLL تنفيذ IExplorerCommandيظهر الأمر في القائمة الجديدةالهدف امتداد أو كلّ الملفّات وما شابه

الشكل 11: إعلانان في البيان يربطان DLL التنفيذ بالهدف، فيظهر الأمر في القائمة الجديدة.

5.3. خيار التطبيق غير المعبَّأ ── الحصول على الهويّة وحدها بحزمة متفرّقة

باب النجاة عندما «تطبيقنا لا يمكن توزيعه إلا كـ MSI؛ MSIX مستحيل» هو حزمة متفرّقة (MSIX بموقع خارجي). توقّع MSIX صغيراً هو بيان فقط، بلا جسم تطبيق، وتسجّله في نهاية المثبِّت القائم. يكتسب التطبيق عندئذٍ هويّة حزمة، ويصير تسجيل البيان أعلاه (= الظهور في القائمة الجديدة) ممكناً. متاحة من ويندوز 10 الإصدار 2004 فصاعداً، وتحتاج الحزمة توقيعاً بشهادة موثوقة على الجهاز الهدف.8

تدفّق الحصول على الهويّة بحزمة متفرّقةبعد أن يضع المثبِّت القائم جسم التطبيق، تسجيل حزمة متفرّقة بيان-فقط بموقع خارجي يعطي التطبيق هويّة حزمة ويجعل تسجيل بيان القائمة الجديدة ممكناًالمثبِّت القائموضع جسم التطبيقحزمة متفرّقةبيان فقط، بلا جسمالتسجيل بموقع خارجياكتساب هويّة حزمةيصير تسجيل القائمة الجديدة ممكناًيلزم توقيع موثوق

الشكل 12: سجّل حزمة متفرّقة لا تحتوي جسماً، بموقع خارجي، فيكتسب التطبيق هويّة حزمة.

أعظم مزيّة أنّك لا تحتاج استبدال المثبِّت؛ هي الإجابة الواقعيّة لتطبيق لديه أصلاً أصل مثبِّت MSI/EXE. لمقارنة مع انتقال كامل إلى MSIX، انظر أيضاً “كيف تختار نموذج توزيع تطبيق Windows - MSI و MSIX و ClickOnce و xcopy والـ custom updaters”.

5.4. كيف تظهر أفعال الارتباط في القائمة الجديدة

نقطة يسهل إساءة فهمها: ارتباطات الفصلين 2 و3 (ProgID والفعل) ما زالت حيّة في القائمة الجديدة. الفعل الافتراضي عند النقر المزدوج، و«فتح»، ومرشَّحو «فتح بواسطة» تُحَلّ من الارتباط وتُعرَض أعلى القائمة الجديدة. لذا إن كان كلّ ما تريده هو «أن تستطيع الفتح بهذا التطبيق»، فويندوز 11 لا يحتاج عملاً إضافيّاً. من الجهة الأخرى، الارتباط ليس امتداد قائمة عامّ الغرض، لذا إن أردت أمراً مخصّصاً اعتباطيّاً في الطبقة الأولى من القائمة الجديدة فأنت بحاجة إلى IExplorerCommand مع الهويّة — هذا تقسيم الأدوار.7

تقسيم الأدوار بين الارتباطات والقائمة الجديدةارتباط ProgID والفعل ما زال يُستخدَم في القائمة الجديدة لحلّ الفعل الافتراضي وفتح وفتح بواسطة، ويُعرَض في الأعلى؛ وضع أمر مخصّص اعتباطي في الطبقة الأولى من القائمة الجديدة يتطلّب IExplorerCommand والهويّةارتباط (ProgID + فعل)حلّ الافتراضي / فتحأعلى القائمة الجديدةلا عمل إضافي في Win11أمر مخصّصIExplorerCommand+الهويّةالطبقة الأولى للقائمة الجديدة

الشكل 13: الارتباطات ما زالت تتولّى حلّ عائلة «فتح» في القائمة الجديدة؛ الأمر المخصّص وحده يتطلّب IExplorerCommand مع الهويّة.

6. جدول قرار عملي ── أيّ الخيارات الثلاثة تتّخذ

ننظّم ما لدينا حتى الآن في اختيار ثلاثي عملي.

ما تريد تحقيقه الوسيلة المستحسَنة كيف يبدو في ويندوز 11 العمل والكلفة المطلوبة
(أ) إطلاق التطبيق الداخلي بالنقر المزدوج أو «فتح» ارتباط + فعل ثابت (تسجيل سجلّ فقط) مدمج في «فتح» و«فتح بواسطة» في القائمة الجديدة تسجيل سجلّ المثبِّت فقط. لا DLL، ولا متطلّب توقيع إضافي
(ب) وضع أمر مخصّص للملف/المجلد المحدَّد في القائمة الجديدة تنفيذ IExplorerCommand + تسجيل بيان MSIX. تطبيق غير معبَّأ يُمنَح الهويّة بحزمة متفرّقة الطبقة الأولى للقائمة الجديدة (عدّة أوامر تُجمَع في قائمة طائرة باسم التطبيق) DLL C++ أصلي + هويّة حزمة + توقيع شيفرة
(ج) الاستمرار في استخدام امتداد IContextMenu كلاسيكي قائم أبقه كما هو الآن (لا تختره لتطوير جديد) جانب القائمة القديمة فقط، تحت «إظهار المزيد من الخيارات» (Shift+F10) صيانة بناء 64 بت وتسجيل COM. خطّط لاحقاً للانتقال إلى (ب)

نقطتا حكم. الأولى، لا تجلب (ب) أو (ج) لمتطلّب تلبيه (أ). لحظة كتابة امتداد صدفة تتولّى مسؤوليّة استقرار المستكشف. الثانية، (ج) «غير معطوب» فحسب؛ كتجربة مستخدم يبقى خطوة أسوأ. كلّما استُخدِم أمر بتواتر أعلى في التشغيل اليومي، كبر عائد الانتقال إلى (ب).

كيف تختار بين الخيارات الثلاثةإن كان كلّ ما تريده إطلاقاً بالنقر المزدوج أو فتح، فالارتباط وفعل ثابت يكفيان؛ لوضع أمر مخصّص في القائمة الجديدة استخدم IExplorerCommand وتسجيل بيان MSIX؛ إن لم تستطع أن تصير MSIX فامنح الهويّة بحزمة متفرّقة؛ أبق امتداد IContextMenu كلاسيكي قائم في جانب القائمة القديمة الآننعملانعمنعملالاهل يكفي فتح؟ارتباط + فعل ثابتمخصّص في القائمة الجديدة؟أتستطيع أن تصير MSIX؟IExplorerCommand+MSIXهويّة حزمة متفرّقةأبق الكلاسيكي الآنجانب القائمة القديمة فقطلا DLL، خطر صغير

الشكل 14: اختر بين فعل ثابت، وIExplorerCommand مع الهويّة، وإبقاء الكلاسيكي، بحسب المتطلّب.

7. النشر والتسجيل عمليّاً ── المثبِّت والحزمة المتفرّقة والتنظيف

7.1. HKLM أم HKCU

طابقه مع شكل المثبِّت. كلّ المستخدمين (موضوع تحت Program Files، حقوق مسؤول) هو HKLM\Software\Classes؛ تثبيت لكلّ مستخدم (بلا رفع) هو HKCU\Software\Classes. اخلطهما فتنتج استفسارات من نوع «أ يستطيع فتحه لكن ب لا يستطيع». لامتداد صدفة يتضمّن تسجيل CLSID، Reg-Free COM — الذي يلغي الحاجة إلى تسجيل السجلّ نفسه — خيار صالح لاستخدام COM داخل التطبيق، لكنّه لا يُطبَّق على امتداد صدفة يحمّله المستكشف، لذا تحتاج التسجيل المباشر (“ما هو Reg-Free COM - كيف يعمل Registration-Free COM وأين يلائم وأين لا يلائم”).

7.2. بعد تغيير، أعلِم ── SHChangeNotify

بعد أن تسجّل ارتباطاً أو تغيّره أو تحذفه، أعلِم حدث SHCNE_ASSOCCHANGED بـ SHChangeNotify. تجاوز هذا وقد يفشل المستكشف في ملاحظة التغيير حتى إعادة التشغيل.110

// Call once after changing associations, e.g. from an installer custom action
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);

7.3. تسجيل حزمة متفرّقة وإزالتها

تسجيل حزمة متفرّقة وإزالتها عمل المثبِّت. سجّل بعد وضع الملفّات؛ أزل قبل حذف الملفّات.8

# At install time: after placing the files, register the install folder as the external location
Add-AppxPackage -Path "C:\Program Files\KomuraSoft\KomuraReport.identity.msix" `
                -ExternalLocation "C:\Program Files\KomuraSoft"

# At uninstall time: remove the package registration before deleting the files
Remove-AppxPackage <package full name>

نقطة للمراقبة: Add-AppxPackage يسجّل للمستخدم الذي شغّله. إن استدعيته من إجراء مخصّص لـ MSI لكلّ الجهاز، يعمل تحت LocalSystem، فإنّ ذلك لا يمنح الهويّة للمستخدم الذي ثبّت، لذا تضبطه ليعمل تحت انتحال شخصيّة المستخدم. حتى عندئذٍ، التسجيل تحت الانتحال فقط للمستخدم الذي شغّل ذلك التثبيت. على حاسوب يستخدمه عدّة مستخدمين، المستخدمون الآخرون والمستخدمون المنشأون لاحقاً بلا هويّة حزمة، ولا يظهر الأمر في القائمة الجديدة. لكي يستخدمه كلّ مستخدم، وفّر آليّة مثل فحص تسجيل حزمتك عند أوّل إطلاق والتسجيل إن غاب (تسجيل لكلّ مستخدم)، واضمِن الإزالة من كلّ مستخدم لديه تسجيل في خطّة إلغاء التثبيت. عكس تسجيل بيان قد يتطلّب أيضاً إعادة تشغيل المستكشف (أو تسجيل الخروج).7

ترتيب تسجيل حزمة متفرّقة وإزالتهاعند التثبيت سجّل الحزمة المتفرّقة بعد وضع الملفّات؛ عند إلغاء التثبيت أزل التسجيل قبل حذف الملفّات؛ راقب أنّ التسجيل نافذ فقط للمستخدم الذي شغّلهتثبيتوضع الملفّاتتسجيل الحزمة المتفرّقةإلغاء التثبيتإزالة تسجيل الحزمةحذف الملفّاتالتسجيل نافذ فقط للمستخدم المشغِّل

الشكل 15: سجّل بعد وضع الملفّات، وأزل قبل حذف الملفّات، وراقب أنّ التسجيل لكلّ مستخدم مشغِّل.

7.4. التنظيف عند إلغاء التثبيت ── ماذا تحذف وماذا تترك

تنظيف إلغاء التثبيت له خطّ دليل رسمي واضح.1

  • احذف: مفتاح الـ ProgID الداخلي بأكمله، تسجيل Capabilities/RegisteredApplications، تسجيل CLSID امتداد الصدفة، الحزمة المتفرّقة (Remove-AppxPackage).
  • اترك: القيمة الافتراضيّة لمفتاح الامتداد (.kmrpt). التوصية الرسميّة ألّا تحذفها حتى إن كانت ما زالت تشير إلى الـ ProgID الداخلي. الحكم بعد التثبيت ما إذا كان تطبيق آخر قد أخذ الافتراضي صعب، وويندوز يتجاهل ببساطة ProgID قيمة افتراضيّة غير مسجَّل، فتركها لا يضرّ فعلاً.
  • استدعِ SHChangeNotify(SHCNE_ASSOCCHANGED) في نهاية التنظيف أيضاً.

معظم مشكلات «ألغينا التثبيت وما زالت بقايا تظهر في القائمة» تسرّب في تصميم هذا التنظيف.

تصميم التنظيف عند إلغاء التثبيتعند إلغاء التثبيت تحذف مفتاح الـ ProgID الداخلي وتسجيل CLSID والحزمة المتفرّقة؛ تترك القيمة الافتراضيّة لمفتاح الامتداد لأنّ ProgID غير مسجَّل يُتجاهَل؛ تعلِم التغيير بـ SHChangeNotify في نهاية التنظيفإلغاء التثبيتاحذفاتركتسجيل ProgID وCLSIDحزمة متفرّقةالقيمة الافتراضيّة لمفتاح الامتدادProgID غير مسجَّل يُتجاهَلأعلِم بـ SHChangeNotify في النهاية

الشكل 16: احذف التسجيل الداخلي، واترك القيمة الافتراضيّة لمفتاح الامتداد، وأعلِم التغيير في نهاية التنظيف.

8. استكشاف الأخطاء ── مفقود، مكرَّر، ثقيل

8.1. لا يظهر في القائمة

اعزل بهذا الترتيب.

  1. أي قائمة تنظر إليها: تسجيل بالأسلوب الكلاسيكي يظهر فقط في جانب القائمة القديمة تحت Shift+F10. افحص الاثنين أوّلاً.
  2. العرض البتّي: DLL امتداد صدفة بـ 32 بت فقط لا يُحمَّل في مستكشف 64 بت (القسم 4.3).
  3. وجهة التسجيل: HKLM/HKCU، خلط Wow6432Node. أكّد المفتاح الفعلي بـ reg query.
  4. تسجيل الحزمة: للقائمة الجديدة، أكّد الوجود بـ Get-AppxPackage، وثقة شهادة التوقيع، ومسار -ExternalLocation، ثمّ أعد تشغيل المستكشف.7
  5. إعلان فائت: إن نُسِي SHChangeNotify، تستطيع أن تعرف بإعادة تشغيل المستكشف هل يسري.
ترتيب العزل عندما لا يظهر في القائمةابدأ بتأكيد أي قائمة تنظر إليها، ثمّ اعزل عرض DLL البتّي، ووجهة تسجيل السجلّ، وتسجيل الحزمة والتوقيع، وSHChangeNotify الفائت، بهذا الترتيبأكّد أي قائمة، قديمة أم جديدةأكّد العرض البتّي للـ DLLأكّد وجهة تسجيل HKLM وHKCUأكّد تسجيل الحزمة والتوقيعاعرف إعلاناً فائتاً بإعادة التشغيل

الشكل 17: عندما «لا يظهر»، اعزل بترتيب القائمة التي تنظر إليها، فالعرض البتّي، فوجهة التسجيل، فتسجيل الحزمة، فالإعلان الفائت.

8.2. يظهر مرّتين، أو لا يختفي

الأسباب النموذجيّة تعايش تسجيل سجلّ كلاسيكي مع تسجيل بيان، أو تسرّب في تنظيف إلغاء التثبيت (القسم 7.4)، أو بقايا ProgID إصدار قديم. إن ظهر مرّتين في القائمة القديمة فقط، فكّر في بقايا؛ إن ظهر في القديمة والجديدة، فكّر في تعايش.

عزل عرض مزدوجمرّتان في القائمة القديمة فقط تشيران إلى بقايا مثل تسرّب تنظيف أو ProgID قديم؛ مرّتان في القديمة والجديدة تشيران إلى تعايش تسجيل سجلّ كلاسيكي مع تسجيل بيانالقائمة القديمة فقطالقديمة والجديدةفي أيّهما يظهر مرّتين؟بقاياتعايشتسرّب تنظيف أو ProgID قديم متروكتسجيل سجلّ كلاسيكي يتعايش مع التسجيل الجديد

الشكل 18: مرّتان في القائمة القديمة فقط تشيران إلى بقايا؛ مرّتان في القديمة والجديدة تشيران إلى تعايش.

8.3. المستكشف ثقيل أو ينهار

عندما يكون النقر الأيمن بطيئاً، أو ينهار مجلد معيّن، جرّد أوّلاً امتدادات الصدفة المثبَّتة. اسرد الامتدادات غير التابعة لمايكروسوفت بأداة مثل ShellExView من NirSoft، وعطّل المشبوهة مؤقّتاً، وابحث ثنائيّاً لتحديد DLL الجاني. عند الانهيار، «Faulting module» في عارض الأحداث أيضاً دليل. إن كان الامتداد الداخلي السبب، اشتبه في إدخال/إخراج متزامن أو وصول شبكة على مسار بناء القائمة (القسمان 4.2 و5.2).

تحديد DLL الجاني عندما يكون ثقيلاً أو ينهاراسرد امتدادات الصدفة غير التابعة لمايكروسوفت في ShellExView، وعطّل المشبوهة مؤقّتاً وابحث ثنائيّاً لتحديد DLL الجاني؛ عند الانهيار وحدة العطل في عارض الأحداث أيضاً دليلجرّد امتدادات الصدفةاسرد غير التابعة لمايكروسوفتعطّل مؤقّتاً وابحث ثنائيّاًحدّد DLL الجانيعند الانهيارافحص وحدة العطل

الشكل 19: عطّل مؤقّتاً الامتدادات غير التابعة لمايكروسوفت وابحث ثنائيّاً؛ عند الانهيار استخدم أيضاً عارض الأحداث.

8.4. Windows Sandbox مريح للتحقّق

التحقّق من تكامل الصدفة أساسه تأكيد «تثبيت في بيئة نظيفة → تشغيل → إلغاء تثبيت → بقايا صفر». المريح هنا Windows Sandbox (Pro/Enterprise/Education): كلّ إطلاق يُحضِر ويندوزاً جديداً قابلاً للرمي في ثوانٍ، فتستطيع تشغيل اختبارات تسجيل المثبِّت وتنظيفه كما تشاء. أغلقه فيختفي كلّ شيء، لذا يناسب أيضاً تحقيق سجلّ البقايا.15

9. الخلاصة

  • ارتباط الملف البنية الثلاثيّة «مفتاح الامتداد → ProgID → الفعل»، وHKCR عرض مدمج لـ Classes في HKLM/HKCU. سمِّ وجهة الكتابة صراحة، ولف دائماً %1 بعلامات اقتباس.
  • التطبيق الافتراضي مصمَّم ليختاره المستخدم ولا يمكن تغييره من برنامج. عمل المثبِّت التسجيل صحيحاً كمرشَّح.
  • امتداد الصدفة الكلاسيكي DLL COM داخل العمليّة يُحمَّل في المستكشف. انهيار أو تأخير ينتشر إلى الكلّ؛ يلزم 64 بت؛ الشيفرة المُدارة غير مدعومة؛ التنفيذ بـ C++ أصلي هو القاعدة.
  • في ويندوز 11 انشطرت قائمة السياق شطرين. وضع أمر مخصّص في القائمة الجديدة يتطلّب IExplorerCommand مع بيان MSIX؛ IContextMenu الكلاسيكي يُنقَل إلى جانب «إظهار المزيد من الخيارات».
  • لتطبيق لا يستطيع أن يصير MSIX، الحصول على الهويّة بحزمة متفرّقة (MSIX بموقع خارجي) هو الإجابة الواقعيّة.
  • إن كان كلّ ما تريده «الفتح بهذا التطبيق»، فما زال الارتباط وفعل ثابت كافيين. البدء من أبسط وسيلة هو الدليل الرسمي أيضاً.
  • بعد التسجيل أو التغيير أو الحذف، أعلِم بـ SHChangeNotify؛ عند إلغاء التثبيت احذف الـ ProgID واترك القيمة الافتراضيّة لمفتاح الامتداد. Windows Sandbox مريح للتحقّق.

إن جعلك استبدال حاسوب بويندوز 11 تلاحظ أنّ «القائمة أُخفيت»، أكّد أوّلاً أيّاً من (أ) و(ب) و(ج) في جدول قرار الفصل 6 هي. ينبغي أن تستطيع تقدير حجم العمل في المكان.

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

مجالات الاستشارة ذات الصلة

شركة كومورا سوفت ذ.م.م. تتولّى تصميم وتنفيذ ارتباط الملف وقوائم السياق وامتدادات الصدفة لتطبيقات الأعمال؛ استهداف قائمة سياق ويندوز 11 الجديدة (الانتقال إلى IExplorerCommand، إدخال حزمة متفرّقة)؛ مراجعة تسجيل مثبِّت قائم وتنظيفه؛ وتحقيق سبب ثقل المستكشف أو انهياره. يحسن أن تبدأ من تقرير ماذا تفعل بـ«القائمة التي أُخفيت تحت إظهار المزيد من الخيارات».

روابط مرجعيّة

  1. Microsoft Learn, File Types. عن بنية مفتاح امتداد يشير إلى ProgID؛ OpenWithProgIds؛ تقسيم التسجيل بين HKLM/HKCU\Software\Classes؛ استدعاء SHChangeNotify(SHCNE_ASSOCCHANGED) بعد تغيير ارتباط؛ وحذف الـ ProgID عند إلغاء التثبيت مع ترك القيمة الافتراضيّة لمفتاح الامتداد.  2 3 4 5

  2. Microsoft Learn, HKEY_CLASSES_ROOT Key. عن كون HKEY_CLASSES_ROOT عرضاً مدمجاً لـ HKLM\Software\Classes وHKCU\Software\Classes؛ تعريفات جانب المستخدم تتقدّم على جانب الجهاز؛ وقواعد التوزيع عند الكتابة.  2

  3. Microsoft Learn, Windows app defaults platform. عن تصميم تغيير التطبيق الافتراضي ليتمّ فقط عبر واجهة إعدادات النظام؛ بيانات إعدادات المستخدم مشوَّشة ومحميّة كتابةً ببرنامج تشغيل ترشيح (UCPD.sys)؛ التغيير المعتمد على السجلّ غير مدعوم؛ واستخدام سياسة المجموعة / MDM في بيئة مُدارة.  2

  4. Microsoft Learn, Working with Shell Extensions. عن أنواع معالج امتداد الصدفة؛ كون الامتداد DLL COM داخل العمليّة يُحمَّل في المستكشف (وفي عمليّات تستضيف الصدفة) بحيث ينتشر انهيار أو تجمّد إلى المستكشف بأكمله؛ التسجيل بـ ThreadingModel=Apartment؛ والنظر في بديل أبسط قبل امتداد صدفة.  2 3

  5. Microsoft Learn, Guidance for Implementing In-Process Extensions. عن أنّ مايكروسوفت لا تستحسن ولا تدعم تنفيذ امتداد صدفة داخل العمليّة بشيفرة مُدارة؛ أسباب تشمل اصطدامات إصدار CLR وإعادة الدخول وعمر الكائن غير الحتمي؛ وقبول الشيفرة المُدارة لامتداد خارج العمليّة (معالج معاينة، أو إطلاق من shell\verb\command).  2 3

  6. Windows Developer Blog, Extending the Context Menu and Share Dialog in Windows 11. عن تصميم قائمة سياق ويندوز 11 الجديدة؛ التوسيع عبر IExplorerCommand مع هويّة التطبيق؛ وضع «فتح» و«فتح بواسطة» في الأعلى؛ جمع عدّة أوامر في قائمة طائرة باسم التطبيق؛ وتحميل امتدادات IContextMenu الكلاسيكيّة كقائمة ويندوز 10 تحت «إظهار المزيد من الخيارات» (Shift+F10).  2 3

  7. Microsoft Learn, Add a File Explorer context menu command to a packaged desktop app. عن أنّ التسجيل في قائمة سياق ويندوز 11 الجديدة يتمّ بتنفيذ IExplorerCommand مع windows.comServer مع إعلان بيان desktop4:FileExplorerContextMenus؛ قدرة ItemType على تحديد * أو Directory أو Directory\Background؛ مطابقة معمارية الـ DLL؛ إبقاء طرائق بناء القائمة سريعة؛ تغطية تطبيق غير معبَّأ بحزمة متفرّقة؛ أنّ إعادة تشغيل المستكشف قد تلزم أحياناً ليسري التسجيل؛ وأنّ ارتباط الملف ليس امتداد قائمة عامّ الغرض.  2 3 4 5 6 7 8

  8. Microsoft Learn, Grant package identity by packaging with external location. عن الحصول على هويّة حزمة بتسجيل حزمة موقع خارجي (حزمة متفرّقة) دون تغيير المثبِّت القائم؛ التوفّر من ويندوز 10 الإصدار 2004 فصاعداً؛ وميزات ويندوز التي تتطلّب الهويّة (تسجيل قائمة السياق والإشعارات وما شابه) تصير قابلة للاستخدام.  2 3

  9. Microsoft Learn, Choosing a Static or Dynamic Shortcut Menu Method. عن اختيار أبسط طريقة فعل ثابت تلبي المتطلّبات؛ IContextMenu الأقوى لكن أيضاً الأعقد ومصنَّف نحو الجانب غير المستحسَن؛ وIExplorerCommand/IExplorerCommandState الطريقة المستحسَنة.  2

  10. Microsoft Learn, SHChangeNotify function. عن كيفيّة رفع حدث SHCNE_ASSOCCHANGED الذي يُعلِم النظام بتغيير ارتباط ملف، وعن استخدامه لكي تلاحظ الصدفة التغيير.  2

  11. Microsoft Learn, Application Registration. عن استحسان تسجيل تنفيذي عبر المفتاح الفرعي App Paths؛ دور المفتاح الفرعي Applications؛ تسجيل الأفعال عبر SystemFileAssociations؛ وأولويّة الـ ProgID والمعلومات المرتبطة عندما يتغيّر التطبيق الافتراضي. 

  12. Microsoft Learn, Creating Shortcut Menu Handlers. عن كيفيّة تسجيل فعل ثابت؛ ترتيب تقرير الفعل الافتراضي (القيمة الافتراضيّة → أوّل فعل → Open → Open With)؛ أسماء عرض الأفعال القياسيّة يوفّرها نظام التشغيل؛ الأفعال الموسَّعة عبر Extended؛ الارتباط بأوامر DDE صار Deprecated؛ وتحفّظات إعادة توجيه WOW64 في بيئة 64 بت.  2 3

  13. Microsoft Learn, Verbs and File Associations. عن كون الفعل عملاً تستخدمه أيضاً ShellExecuteEx؛ عناصر سلسلة أمر قد تحتوي مسافة يلزم لفّها بعلامات اقتباس، و”%1” تُكتَب دائماً مقتبسة؛ وتسجيل إجراء افتراضي تحت HKCR\Applications. 

  14. Microsoft Learn, IExplorerCommand interface. عن تكوين طرائق GetTitle وGetIcon وGetState وInvoke وEnumSubCommands وما شابه؛ استدعاء الطرائق على خيط واجهة المستخدم لذا يجب ألّا تتواصل مع موارد شبكة؛ والتوفّر من ويندوز فيستا فصاعداً. 

  15. Microsoft Learn, Windows Sandbox. عن القدرة على إطلاق بيئة ويندوز معزولة قابلة للرمي في ثوانٍ، وتجاهل كلّ التغييرات عند الإغلاق، وملاءمتها لاختبار البرمجيّات والتحقّق من المثبِّت، والتوفّر على Pro/Enterprise/Education. 

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

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

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

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

لماذا يظهر عنصر قائمة السياق لتطبيقنا في ويندوز 11 تحت «إظهار المزيد من الخيارات» فقط؟
لأنّ قائمة سياق مستكشف الملفّات في ويندوز 11 انقسمت إلى طبقتين، قديمة وجديدة. الأوامر الوحيدة التي يمكن أن تظهر في القائمة الجديدة هي التي تنفّذ واجهة IExplorerCommand ومسجَّلة في بيان حزمة MSIX (= لديها هويّة حزمة). امتدادات الصدفة الكلاسيكيّة المعتمدة على IContextMenu نُقِلت إلى القائمة القديمة التي تُفتَح بـ«إظهار المزيد من الخيارات» (Shift+F10). الامتداد نفسه ليس معطوباً، لذا يستمرّ في العمل حالياً، لكن إن أردته في القائمة الجديدة فأنت بحاجة إلى ترحيل إلى IExplorerCommand وإمّا التعبئة كـ MSIX أو منح الهويّة بحزمة متفرّقة.
هل يستطيع المثبِّت تعيين تطبيقنا تطبيقاً افتراضيّاً للملف (التطبيق الذي يُفتَح بالنقر المزدوج)؟
لا. اختيار التطبيق الافتراضي مصمَّم ليكون ما يفعله المستخدم، وويندوز لا يدعم تغيير التطبيق الافتراضي من أي مكان غير واجهة إعدادات النظام. معلومات UserChoice التي تحمل اختيار كلّ مستخدم مشوَّشة، وبرنامج تشغيل ترشيح (UCPD.sys) يحميها أيضاً من كتابة التطبيقات. ما يستطيع المثبِّت فعله هو تسجيل ProgID وأفعال، وإضافة نفسه إلى OpenWithProgIds ليظهر مرشَّحاً تحت «فتح بواسطة»، وتوجيه المستخدم إلى صفحة إعدادات التطبيقات الافتراضيّة. التنفيذ الصحيح ليس سرقة الافتراضي، بل الاستعداد لأن يُختار.
هل يجوز كتابة امتداد صدفة بشيفرة مُدارة مثل C#؟
صرّحت مايكروسوفت بوضوح أنّ كتابة امتداد صدفة داخل العمليّة (معالج قائمة سياق، معالج أيقونة، وما شابه) بشيفرة مُدارة غير مستحسَنة وغير مدعومة. يُحمَّل الامتداد في المستكشف وفي عمليّة أي تطبيق يفتح حوار ملف شائع، فاصطدامات إصدار CLR وإعادة الدخول وعمر الكائن غير الحتمي تجعل التطبيق المضيف غير مستقر. التنفيذ بـ C++ أصلي هو القاعدة. ملف EXE عادي يُطلَق من أمر الفعل، أو امتداد خارج العمليّة مثل معالج معاينة يعمل في عمليّة منفصلة، مقبولان بالشيفرة المُدارة.
ما الحزمة المتفرّقة (MSIX بموقع خارجي)؟
حزمة MSIX صغيرة لا تحتوي ملفّات التطبيق، بل بياناً فقط (معلومات الهويّة). لتطبيق مُثبَّت بالطريقة العاديّة بمثبِّت قائم (MSI وInno Setup وما شابه)، تسجّله بـ Add-AppxPackage -ExternalLocation مشيراً إلى مجلد التثبيت، فيكتسب التطبيق هويّة حزمة ويستطيع استخدام ميزات تتطلّب الهويّة، مثل التسجيل في قائمة سياق ويندوز 11 الجديدة وإشعارات التوست. متاحة من ويندوز 10 الإصدار 2004 فصاعداً، وتحتاج الحزمة توقيع شيفرة موثوقاً على الجهاز الهدف. الخيار الواقعي عندما تريد دعم القائمة الجديدة دون نقل أسلوب التوزيع بأكمله إلى MSIX.
ماذا أفعل عندما يظهر عنصر قائمة سياق مرّتين، أو لا يختفي؟
اعزل السبب أوّلاً بالتحقّق من القائمة التي يظهر فيها: القائمة الجديدة أم القديمة (إظهار المزيد من الخيارات). العرض المزدوج النموذجي أن يتعايش تسجيل سجلّ كلاسيكي مع تسجيل بيان MSIX، أو أن يُترَك تسجيل ProgID أو CLSID امتداد عند إلغاء التثبيت. بعد تغيير الارتباطات، اشتبه أيضاً في نسيان SHChangeNotify(SHCNE_ASSOCCHANGED)؛ فور تسجيل الحزمة، اشتبه في نسيان إعادة تشغيل المستكشف. إن لم يُحَلّ ذلك، عطّل مؤقّتاً الامتدادات غير التابعة لمايكروسوفت في ShellExView وابحث ثنائيّاً لتحديد DLL الجاني.

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

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

غو كومورا

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

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

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