حبّ المطوّر الغريب، أو كيف تعلّمت التوقف عن القلق وأحببتُ Windows
· غو كومورا · Windows, تطوير Windows, التوافق مع الإصدارات السابقة, COM, ActiveX, QA, الفلسفة
1. الخلاصة أوّلاً
عند بناء تطبيقات Windows، هناك الكثير مما يستدعي القلق.
هل ستعمل هذه النسخة على هذا الحاسوب؟ هل ستعمل في بيئة من دون صلاحيات المدير (administrator)؟ هل ستنهار بسبب الفرق بين 32-bit و64-bit؟ مسارات باليابانية، مسارات طويلة، أقراص شبكة، DLL قديمة، مكوّنات COM، ActiveX، طابعات، اتصال تسلسلي (serial)، برامج مضادّة للفيروسات، Windows Update.
بمجرّد أن تبدأ التفكير في الأمر، لا ينتهي القلق.
لكن في مرحلة ما، بدأت أرى الأمر بشكل مختلف.
لعلّ هذا ليس عيباً، بل دليلاً على أنّ Windows حمل على عاتقه أعمالاً واقعية.
Windows ليس مدينة فاضلة نقيّة. لكنّه يحمل في داخله البرمجيات والأجهزة وسير العمل والعادات البشرية التي ظلّت تعمل في الميدان طوال عقود.
هذه الفوضى بالذات هي ما يجعل Windows مثيراً للاهتمام، وما يجعله - من منظور المطوّر - جديراً بالمواجهة.
2. تطوير تطبيقات Windows يحمل الكثير من دواعي القلق
في تطوير تطبيقات Windows، لا يكفي أن يكون «الكود صحيحاً».
يعمل في البيئة المحلية. يعمل على حاسوب المطوّر. يعمل حتى على الجهاز الافتراضي (VM) الخاص بالاختبار.
ومع ذلك، لا ضمانة أن يعمل على حاسوب العميل.
على سبيل المثال، تحدث أمور كهذه:
- تعذّر العثور على DLL
- بيئة تشغيل Visual C++ غير مثبَّتة
- إصدار .NET Framework غير متطابق
- فشل تحميل DLL بصيغة 32-bit من عملية (process) بصيغة 64-bit
- تسجيل COM تالف
- الخلط بين نسختَي
regsvr32.exeالخاصتَين بـ 32-bit و64-bit - كود يفترض دليلاً حالياً (current directory) ثابتاً ينهار تحت جدولة المهام (Task Scheduler)
- محاولة الكتابة داخل
Program Filesتؤدّي إلى خطأ في الصلاحيات - الخلط بين استخدام
AppData\RoamingوAppData\Local - انهيار عند وجود أسماء مستخدمين أو أسماء مجلدات باليابانية
- تعذّر فتح الملفات بسبب مسارات طويلة
- يعمل على قرص شبكة مُعرَّف (mapped) لكن لا يعمل عبر مسار UNC
- انهيار الواجهة في بيئات DPI العالي
- انزياح حسابات الإحداثيات مع تعدّد الشاشات
- اختلاف نتيجة الطباعة باختلاف مشغّل الطابعة (printer driver)
- عدم التعرّف على أجهزة USB والكاميرات وأجهزة القياس والاتصال التسلسلي بحسب البيئة
- حجب برنامج مكافحة الفيروسات جزءاً من المعالجة
- تغيّر السلوك بعد تحديث Windows
عند سرد كلّ هذا، يصيب المرء دوار خفيف.
المشاكل التي تبقى، في تطبيق الويب، محصورة بين المتصفّح والخادم، تنتشر في تطبيق Windows عبر الحاسوب بأكمله. نظام الملفات، سجل النظام (registry)، ملفات تعريف المستخدمين، الطابعات، الأجهزة، الشبكة، سياسات الأمان، برامج التثبيت، بيئات التشغيل.
التطبيق لا «يعمل فوق نظام التشغيل» بقدر ما يوضَع في قلب بيئة عمل واقعية.
لهذا فإنّ تطوير تطبيقات Windows صعب. لكن اختزال ذلك في عبارة «Windows سيّئ» يبدو لي تبسيطاً مخلّاً.
فما يقوم على هذا الأساس هو تعقيد العالم الواقعي.
3. Windows هو نظام تشغيل الميدان
Windows ليس نظام تشغيل موجوداً فقط من أجل أحدث التقنيات.
المصانع، المستشفيات، الدوائر الحكومية، المدارس، المختبرات، جهات البثّ، معدّات الفحص، منصّات الاستقبال، أجهزة طباعة النماذج، المستودعات، المتاجر، المحاسبة، الرواتب، إدارة المخزون. في أماكن كهذه، لا تزال أعداد هائلة من حواسيب Windows تعمل حتى اليوم.
وما يوجد هناك ليس فقط أحدث خدمات الويب.
هناك ماكرو Excel. هناك Access. هناك تطبيقات VB قديمة. هناك تطبيقات أعمال مبنيّة على .NET Framework. هناك تطبيقات مقيمة (resident) مكتوبة بـ C++. هناك مكوّنات COM. هناك ActiveX. هناك اتصالات ODBC. هناك مشغّلات طابعات. هناك قارئات باركود. هناك أجهزة قياس تعمل بالاتصال التسلسلي. هناك حزم SDK من موردي الأجهزة.
والأهمّ من ذلك، أنّ لا شيء من هذا موجود بمعزل عن غيره.
الناس يشغّلونها، يطبعون النماذج، يستبدلون أجهزة USB، يضعون ملفات CSV في مجلدات مشتركة؛ وتعمل المهامّ الدفعية (batch) ليلاً، ثمّ يبدأ العمل من جديد في صباح اليوم التالي. كلّ هذا يعمل ضمن هذا التسلسل المتواصل.
Windows ليس مجرّد أساس لتشغيل التطبيقات. إنّه منصّة تستوعب العمل اليومي في الميدان، والأصول القائمة، والأجهزة الطرفية، بل وحتى عادات البشر.
لهذا يبدو أحياناً قديماً. أحياناً معقّداً. وأحياناً يتساءل المرء لماذا لا يزال هذا الشيء موجوداً أصلاً.
لكنّ ذلك يعني أيضاً أنّه لم يتخلَّص من القديم باستهتار قطّ.
4. التوافق مع الإصدارات السابقة كصورة من صور الحبّ
لو كان الهدف الوحيد هو جعل نظام التشغيل يبدو جميلاً، لكان من الأسهل ببساطة قطع الآليات القديمة.
حذف واجهات API القديمة. حذف بيئات التشغيل القديمة. حذف شاشات الإعدادات القديمة. معاملة التطبيقات القديمة على أنّها ببساطة لم تعد تعمل.
لو فُعل ذلك، لربما أصبح التصميم أنظف. ولربما قصرَت الوثائق. ولربما شعر المطوّرون بارتياح أكبر قليلاً.
لكن وراء ذلك، هناك تطبيقات أعمال ستتوقّف عن العمل. وهناك معدّات ستتوقّف. وهناك مواقع عمل ستقع في مأزق.
التوافق مع الإصدارات السابقة في Windows مزعج تقنياً بالفعل.
هناك WOW64، لتشغيل تطبيقات 32-bit على Windows بصيغة 64-bit.
سجل النظام وملفات DLL قد تظهر بشكل مختلف للكود بصيغة 32-bit وللكود بصيغة 64-bit.
هناك ذلك البنيان المُربك للوهلة الأولى، حيث C:\Windows\System32 هو الجانب الخاصّ بـ 64-bit، وC:\Windows\SysWOW64 هو الجانب الخاصّ بـ 32-bit.
COM أيضاً مزعج. لا يكفي مجرّد وضع DLL في مكانها؛ فقد يلزم تسجيلها. هل التسجيل على مستوى المستخدم أم على مستوى الجهاز؟ هل هو COM بصيغة 32-bit أم 64-bit؟ هل تلزم صلاحيات المدير؟
الأمر ذاته ينطبق على .NET Framework.
اليوم يوجد خيار استخدام .NET حديث مثل .NET 8 أو .NET 9.
لكن في الميدان، لا تزال تطبيقات .NET Framework 4.x موجودة حتى الآن.
وهذا ليس مجرّد قِدَم؛ بل يعني أنّ هذا الإصدار ظلّ يدعم عملاً واقعياً لسنوات طويلة.
التوافق مع الإصدارات السابقة ليس مفهوماً جميلاً فحسب. بل هو، بالأحرى، مسؤولية ثقيلة.
إبقاء الأشياء القديمة تعمل يعني حمل دَين تقني. لكنّه في الوقت نفسه صورة من صور النزاهة: عدم إيقاف عمل المستخدمين.
وأعتقد أنّ هنا بالذات يكمن ما يستحقّ الحبّ في Windows.
5. Windows نظام تشغيل أشبه بالطبقات الجيولوجية
في Windows، تراكمت تقنيات كلّ حقبة فوق بعضها كطبقات جيولوجية.
Win32. COM. ActiveX. Windows Forms. WPF. .NET Framework. UWP. WinUI. Windows App SDK. MSIX. PowerShell. Windows Terminal. WSL.
لكلّ منها حقبة ظهورها، ومجالات تفوّقها، ومواقع الميدان التي استُخدمت فيها.
إن نظرتَ إلى الجديد فقط، فقد يبدو القديم عائقاً. لكن في تطوير تطبيقات Windows، توجد غالباً مواقف لا يمكن فيها تجاهل الطبقات القديمة.
فمثلاً، حتى عند بناء تطبيق WPF، قد تصطدم الطباعة بمشاكل GDI ومشغّلات الطابعات. وحتى عند الكتابة بلغة C#، إذا كانت حزمة SDK الخاصّة بمورّد ما عبارة عن DLL أصلية (native)، فستواجه مشاكل P/Invoke ومشاكل عدد البتّات (bitness). وحتى عند بناء شاشات جديدة، قد يلزم أحياناً الإبقاء على مكوّنات COM قائمة أو على التكامل مع Excel.
Windows ليس حديقة منظّمة بالكامل. بل هو أقرب إلى مدينة ضخمة تعرّضت للتوسيع وإعادة البناء مراراً وتكراراً.
فيها شوارع رئيسية واسعة. وفيها ممرّات تحت أرضية. وفيها أزقّة قديمة. وفيها أبراج جديدة شاهقة.
يسهل أن تضيع فيها. لكن في أعماق تلك الأزقّة، لا يزال يعمل حتى اليوم عمل مهمّ.
ما يحتاجه المطوّر ليس الحكم بأنّ «القديم يعني غير الضروري». بل القدرة على تمييز أيّ طبقة من التقنية تدعم أيّ عمل.
6. تحويل الإرهاق إلى تصميم
في العنوان جاءت عبارة «التوقف عن القلق».
لكنّ التوقف عن القلق لا يعني التراخي. كما لا يعني التظاهر بعدم رؤية المشاكل.
التوقف عن القلق يعني تحويل القلق إلى تصميم.
فمثلاً، إن كان القلق يتعلّق بمسألة هل سيعمل التطبيق، حوِّل التحقّق من التشغيل إلى اختبار دخانيّ (smoke test).
Start-Process .\MyApp.exe
ولا تكتفِ بمجرّد التحقّق من التشغيل، بل جرّب أيضاً من دون ملفّ إعدادات، من دون مجلّد سجلّات (log)، بصلاحيات مستخدم عادية، من دون اتصال شبكة، من دون طابعة مُعدّة، وبـ DPI عالٍ، ومسارات طويلة، ومسارات باليابانية.
إن كان القلق يتعلّق بـ DLL، تحقّق من التبعيات (dependencies). وإن كانت بيئة تشغيل Visual C++ مطلوبة، قرّر ما إذا كنت ستضمّها إلى برنامج التثبيت أم تنصّ عليها صراحةً كشرط مسبق. وإن كنت تستخدم ملفات DLL أصلية، لا تترك العلاقة بين x86 وx64 وAnyCPU غامضة.
إن كان القلق يتعلّق بـ COM، دوّن خطوات التسجيل في دليل إجرائي وأعِد تنفيذها من الصفر على حاسوب اختبار.
# مثال: تسجيل DLL خاص بـ COM بصيغة 64-bit
C:\Windows\System32\regsvr32.exe .\SomeComponent64.dll
# مثال: تسجيل DLL خاص بـ COM بصيغة 32-bit
C:\Windows\SysWOW64\regsvr32.exe .\SomeComponent32.dll
إن كان القلق يتعلّق بالصلاحيات، تجنّب التصاميم التي لا تعمل إلا بصلاحيات المدير.
ضَع إعدادات المستخدم في AppData، وإعدادات الجهاز بأكمله في ProgramData.
تجنّب التصاميم التي تكتب سجلّات (logs) داخل Program Files.
إن كان القلق يتعلّق بالمسارات، أدرِج في اختباراتك الأحرف اليابانية، والمسافات، وأسماء المجلدات الطويلة، ومسارات UNC.
New-Item -ItemType Directory -Path "C:\テスト 用\とても長いフォルダー名\さらに深いフォルダー" -Force
إن كان القلق يتعلّق بـ DPI، تحقّق عند 100%، و125%، و150%، و200%. ومع تعدّد الشاشات، تحقّق من عدم انهيار أيّ شيء عند الانتقال بين شاشات ذات نسب تكبير مختلفة. ولأنّ WinForms وWPF وWinUI تتعامل مع دعم DPI كلّ بطريقته الخاصّة، تحقّق من كلّ تقنية واجهة على حدة.
إن كان القلق يتعلّق بالذاكرة والمقابض (handles)، استخدم Application Verifier وWinDbg وProcDump وProcess Explorer وما شابهها. إن كان القلق يتعلّق بالانهيارات، احتفظ بسجلات الأحداث (event logs) والتفريغات (dumps) وسجلّات التطبيق.
Get-EventLog -LogName Application -Newest 20
أو، في البيئات الأحدث، تحقّق من سجلّ الأحداث على هذا النحو:
Get-WinEvent -LogName Application -MaxEvents 20
إن كان القلق يتعلّق بأعطال لا يمكن إعادة إنتاجها في الميدان، ارفع دقّة التسجيل (logging granularity). عبارة «حدث خطأ» لا تكفي. ما هو الملفّ الذي كانت المحاولة تفتحه؟ ما هو الجهاز الذي كان يُبحث عنه؟ تحت أيّ مستخدم كانت العملية تُنفَّذ؟ في أيّ مسار كانت هناك محاولة للكتابة؟ أيّ DLL تعذّر تحميله؟
حوِّل القلق إلى شيء قابل للملاحظة.
هذا أمر بالغ الأهمّية في تطوير تطبيقات Windows.
7. «يعمل على حاسوب العميل» هو الهدف النهائيّ
أن يعمل التطبيق في بيئة التطوير أمر مهمّ. أن تنجح الاختبارات في CI أمر مهمّ. أن يعمل على جهاز افتراضيّ (VM) نظيف أمر مهمّ.
لكن بالنسبة لتطبيق Windows، فإنّ العائق الأخير يبقى دائماً: «هل يعمل على حاسوب العميل؟»
ذلك الحاسوب لديه بالفعل أشياء مثبَّتة. ربما فيه مشغّل طابعة قديم. ربما فيه برنامج أمان خاصّ بالشركة. ربما هناك أقراص شبكة معرَّفة (mapped). ربما لا يملك المستخدم صلاحيات المدير. ربما هناك أسباب تمنع تطبيق Windows Update فوراً. ربما تكون بيئة بلا اتصال بالإنترنت.
لهذا فإنّ طريقة التوزيع مهمّة أيضاً.
هل يكفي مجرّد تسليم ملفّ exe؟ هل ينبغي أن يكون MSI؟ ClickOnce؟ MSIX؟ هل يمكن التوزيع عبر winget؟ هل سيُدرَج ضمن نظام توزيع داخليّ؟ هل يلزم مثبّت يعمل دون اتصال (offline)؟ هل يلزم توقيع الكود (code signing)؟ هل سيحجبه SmartScreen أو برنامج مكافحة الفيروسات؟
لا يقترب المرء فعلياً من حالة «قابل للاستخدام في الميدان» إلا حين يشمل، إلى جانب التطبيق نفسه، عمليات التثبيت والتحديث وإلغاء التثبيت وجمع السجلّات وإجراءات الاستعادة.
في تطوير تطبيقات Windows، لا ينتهي البرنامج عند التسليم. بل يجب أن يعمل في بيئة العميل، اليوم وغداً على حدّ سواء.
8. لماذا أحبّ Windows رغم كلّ ذلك
لدى Windows جوانبه المرهقة. هذه حقيقة.
DLL. COM. سجل النظام (registry). UAC. DPI. الطابعات. بيئات التشغيل. 32-bit / 64-bit. أقراص الشبكة. المسارات الطويلة. البيئات اليابانية اللغة. برامج الأمان. Windows Update.
إن أخذت تسرد المرهقات، فلن تنتهي أبداً.
لكنّ معظم هذا الإرهاق مصدره أنّ Windows حمل على عاتقه، لفترة طويلة جدّاً، عملاً واقعياً.
فهو لا يتخلّى عن الأصول القديمة، بل يستوعب التقنيات الجديدة أيضاً؛ ولديه واجهة رسومية وسطر أوامر معاً؛ ويحتضن التطبيقات المحلّية والويب، والأجهزة الطرفية ومحطّات العمل، والحواسيب الشخصية وحواسيب الشركات على حدّ سواء.
هذه ليست فلسفة واحدة جميلة.
لكنّها قويّة.
وكمطوّر، تستحقّ أن تُواجَه.
بناء برمجيات تعمل بشكل موثوق على Windows لا يعني مجرّد استدعاء واجهات API. بل يعني قراءة قيود الميدان، وفهم الأصول القائمة، وإيجاد النقاط الهشّة، والاختبار، والملاحظة، وإصلاح ما يلزم إصلاحه.
هذا عمل غير لافت. لكنّه ذو قيمة.
9. خلاصة
في تطوير تطبيقات Windows، لا تنتهي دواعي القلق أبداً.
لكنّ معظم هذا القلق هو أيضاً نتيجة أنّ Windows، كنظام تشغيل، استوعب على مدى زمن طويل جدّاً عملاً واقعياً، ومواقع ميدانية واقعية، ومعدّات واقعية، وتصرّفات بشرية واقعية.
لهذا فأنا لا أعتبر Windows مجرّد نظام تشغيل قديم.
إنّه منصّة ضخمة ومعقّدة، وقليلة الرشاقة أحياناً، ظلّت تعمل بينما تتصالح مع الواقع.
وبناء برمجيات تعمل عليه بشكل موثوق لا يزال يحمل حتى اليوم قيمة كبيرة.
التوقف عن القلق.
لكن هذا لا يعني التراخي.
تحويل القلق إلى تصميم واختبار وملاحظة.
وهكذا، شيئاً فشيئاً، أحببتُ Windows.
روابط مرجعية
- Application Verifier - Overview - Microsoft Learn
- High DPI Desktop Application Development on Windows - Microsoft Learn
- Setting the default DPI awareness for a process - Microsoft Learn
- Running 32-bit Applications - Microsoft Learn
- Maximum Path Length Limitation - Microsoft Learn
- MSIX documentation - Microsoft Learn
- Version compatibility in .NET Framework - Microsoft Learn
مقالات ذات صلة
أحدث المقالات التي تشترك في نفس الوسوم. عمّق فهمك بمواضيع مرتبطة.
التعهيد الخارجي والتطوير التعاقدي لتطبيقات Windows: ما ينبغي تنظيمه قبل الطلب
قبل تكليف جهة خارجية بتطوير تطبيق Windows تعاقديّاً، إليك النقاط التي ينبغي تنظيمها: تعديل البرمجيّات القائمة، وتكامل الأجهزة، وCOM/Activ...
ما يجب التحقّق منه عندما لا يعمل ActiveX على Office 2024 / Microsoft 365 - الترتيب العمليّ لتغطية التعطيل الافتراضيّ، 32bit / 64bit، تسجيل COM، DLL التابعة، ووصولًا إلى IE mode
دليل عمليّ لتشخيص توقّف ActiveX على Office 2024 و Microsoft 365، يرتّب الفحوص من التعطيل الافتراضيّ إلى تطابق 32bit / 64bit وتسجيل COM وD...
المزالق الشائعة في تطوير مكوّنات COM و OCX / ActiveX - فخاخ Visual Studio بين 32-bit و 64-bit، والتسجيل، وصلاحيّات المسؤول
دليل عمليّ يكشف الأسباب الحقيقيّة لإخفاق مكوّنات COM و OCX و ActiveX: عدم تطابق 32-bit / 64-bit مع Visual Studio 2022، وأخطاء regsvr32 و ...
ما هي COM / ActiveX / OCX - دليل عمليّ للفروق والعلاقات بينها
نظرة عمليّة لتمييز COM و ActiveX و OCX، مع علاقتها بـ OLE وأماكن استخدامها، لمساعدتك على فصل الأساس عن سياق المكوّن عن الملفّ في تحقيقات ...
ما هو COM - لماذا لا يزال تصميم Windows COM يبدو جميلاً حتى اليوم
يوضّح المقال بإيجاز ما هو COM وما يجعل تصميم Windows COM أنيقاً عبر IUnknown و GUID والتوافق الثنائي، ويبيّن لماذا لا يزال هذا النموذج حا...
أين يتصل هذا الموضوع
ترتبط هذه المقالة بشكل طبيعي بصفحات الخدمات التالية.
تطوير تطبيقات ويندوز
ندعم تطوير برامج ويندوز للأعمال، وتكامل الأجهزة، وأدوات التواصل.
دعم إعادة استخدام الأصول القديمة وترحيلها
ندعم إعادة استخدام وترحيل الأصول التي تحمل قيود COM / ActiveX / OCX أو 32bit / 64bit.
الملف الشخصي للمؤلف
صفحة الملف الشخصي لمؤلف المقالة.
غو كومورا
مؤسّس شركة كومورا سوفت ذ.م.م.
يركّز على تطوير برامج ويندوز، والاستشارات التقنية، والتحقيق في الأخطاء، ويتميّز في المشاريع التي تبقى فيها الأصول القديمة ناشطة، وفي تشخيص الأعطال التي يصعب تحديد سببها.
روابط عامة