هل WebView2 خليفة مناسبة لوضع IE؟ ── قيد عدم عمل ActiveX وتصميم واقعيّ للانتقال

· آخر تحديث: · · WebView2, Windows, .NET, WPF, Windows Forms, وضع IE, ActiveX, الانتقال من الأنظمة القديمة, الأنظمة الداخليّة, الاستشارات التقنيّة

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

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

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

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

غو كومورا (2026). هل WebView2 خليفة مناسبة لوضع IE؟ ── قيد عدم عمل ActiveX وتصميم واقعيّ للانتقال. شركة كومورا سوفت ذ.م.م.. https://doi.org/10.5281/zenodo.21621595 https://comcomponent.com/ar/blog/webview2-embed-web-ui-in-windows-apps/

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

في المقال السابق «كيف نُطيل عمر نظام ويب داخليّ معتمِد على وضع IE، وكيف نخرج منه» كتبنا أنّ وضع IE ليس سوى إجراء إطالة عمر مؤقّت ذي أجل محدود، وأنّه ينبغي تصميم «مخرج» له بالتوازي. وعند تلقّي استشارات حول هذا «المخرج»، يظهر WebView2 بتواتر عالٍ. «نريد عرض نظام الويب الداخليّ داخل تطبيق مخصَّص»، «نريد بناء جزء من شاشات تطبيق سطح المكتب بتقنيّة الويب فقط»، «سمعنا أنّ Electron ثقيل، فهل يوجد بديل؟» ── في كلّ هذه الحالات يبرز WebView2 كخيار.

ومن جهة أخرى، لـ WebView2 طبائع ينبغي معرفتها قبل الاعتماد. كيف تُوزَّع بيئة التشغيل، وأين يُوضع مجلد بيانات المستخدم، وكيف يتحادث الجانب الأصليّ مع جانب الويب. والأهمّ من ذلك قيد يمسّ جوهر خطّة الانتقال: ActiveX الذي كان يعمل في وضع IE لا يعمل في WebView2. يرتّب هذا المقال من البنية الأساسيّة لـ WebView2 إلى التوزيع والتصميم والأمان، وصولاً إلى طريقة الجمع الواقعيّة مع الخروج من وضع IE.

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

  • WebView2 عنصر تحكّم يضمّن Microsoft Edge القائم على Chromium داخل تطبيق Windows. يُستخدَم من WinForms / WPF / WinUI / Win32 C++، ويناسب إضافة «واجهة ويب لجزء من الشاشات فقط» إلى تطبيق سطح مكتب قائم.1
  • بيئة التشغيل مبدأها Evergreen (بيئة تشغيل مشتركة تُحدَّث تلقائيّاً). مدمجة افتراضيّاً في Windows 11، لكن التوصية الرسميّة ألا تفترض «أنّها موجودة»، بل تدمج فحص الوجود وbootstrap في المثبِّت.2
  • للبيئات غير المتّصلة وللمصانع وخطوط الإنتاج التي تريد تجميد تكوين مُتحقَّق منه توجد Fixed Version (مرفقة مع التطبيق)، لكن حجم المرفق يتجاوز 250 ميغابايت، وتتحمّل مسؤوليّة توزيع تحديثات الأمان بنفسك. لا تخترها باستخفاف.3
  • أوّل مطبّ هو مجلد بيانات المستخدم (UDF). يُنشأ افتراضيّاً بجوار exe، فتفشل التطبيقات المُثبَّتة تحت Program Files عند البدء. الأسلوب المتعارف عليه تحديد مجلد تحت %LOCALAPPDATA% صراحةً.4
  • التكامل بين الأصليّ والويب أساسه تبادل الرسائل عبر PostWebMessageAsJson / WebMessageReceived، ويُقصَر AddHostObjectToScript (كشف كائن COM) على محتوى موثوق.1
  • ActiveX لا يعمل داخل WebView2. لا يمكن إنهاء الأمر بـ«نقل صفحات وضع IE المعتمِدة على ActiveX إلى WebView2»، بل يلزم تصميم ينقل المعالجة التي كان يتولّاها ActiveX إلى الجانب الأصليّ. هنا جوهر خطّة الخروج من وضع IE.5

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

2. البنية الأساسيّة لـ WebView2

يتكوّن WebView2 من اثنين: «SDK (واجهات برمجيّة تُدمَج في التطبيق)» و«بيئة التشغيل (بيئة تنفيذ قائمة على Edge تُثبَّت على العميل)». الصورة نفسها لصورة بيئة Visual C++ أو بيئة .NET: يبني التطبيق بالرجوع إلى حزمة NuGet Microsoft.Web.WebView2، ويعمل وقت التشغيل ببيئة التشغيل الموجودة على العميل.3

المنصّات المدعومة واسعة: WinForms وWPF على .NET Framework 4.6.2 فما فوق / .NET Core 3.1 فما فوق، وWinUI، وWin32 C++. المزيّة الكبيرة مقابل أسلوب استبدال الإطار بالكامل (مثل Electron) هي إمكان الاستخدام المتدرّج، كأن تجعل شاشة واحدة فقط من تطبيق أعمال WinForms قائم تستخدم WebView2. لاختيار إطار واجهة المستخدم نفسه راجع أيضاً «جدول قرار WinForms / WPF / WinUI».

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

البند المحتوى
أنظمة تشغيل العميل المدعومة Windows 10 (SAC 1709 فما فوق)، إصدارات LTSC / IoT Enterprise من Windows 10، Windows 116
أنظمة تشغيل الخادم المدعومة Windows Server 2016 / 2019 / 2022 (LTSC)، Windows Server (SAC)6
بيئات التطوير المدعومة Win32 C/C++، .NET Framework 4.6.2 فما فوق، .NET Core 3.1 فما فوق، .NET 5 فما فوق، WinUI 2.0 / 3.06
IDE Visual Studio 2017 فما فوق. الدروس الرسميّة تنصّ صراحةً على أنّها لا تغطّي Visual Studio Code7
SDK حزمة NuGet Microsoft.Web.WebView2 (تُضاف لكلّ مشروع)7
المطلوب وقت التشغيل بيئة تشغيل WebView2. المبدأ Evergreen، ومدمجة افتراضيّاً في Windows 11 (الفصل 3)3
أجهزة غير Windows يمكن استخدامها أيضاً على Xbox وHoloLens 26

أصغر تضمين يكون بشيفرة كهذه (الفكرة مشتركة بين WPF وWinForms).

var env = await CoreWebView2Environment.CreateAsync(
    browserExecutableFolder: null,   // Evergreen ランタイムを使う
    userDataFolder: Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
        "KomuraSoft", "MyApp", "WebView2"));
await webView.EnsureCoreWebView2Async(env);
webView.CoreWebView2.Navigate("https://internal.example.co.jp/app/");

النقطة أنّك تنشئ CoreWebView2Environment بنفسك بدل الاتّكال على الافتراضيّ. السبب في الفصلين التاليين.

خطوات الإدخال نفسها مستقيمة، وفي WinForms / WPF المسار كالتالي.

  1. أضِف Microsoft.Web.WebView2 إلى المشروع عبر NuGet (يظهر عنصر WebView2 أيضاً في صندوق أدوات المصمِّم)
  2. ضع العنصر على النموذج / النافذة
  3. هيِّئ بـ EnsureCoreWebView2Async كما في الشيفرة أعلاه ثمّ Navigate

وهنا تنبيه واجهة برمجيّة ينبغي تثبيته من البداية. webView.CoreWebView2 يكون null إلى أن تكتمل التهيئة. الاشتراك في أحداث مثل CoreWebView2.WebMessageReceived += ... من منشئ النموذج فيصيب NullReferenceException مطبّ كلاسيكيّ، والأساس تجميع معالجة التهيئة «بعد await لـ EnsureCoreWebView2Async». تعيين خاصّيّة Source يبدأ التهيئة ضمنيّاً، لكنّ التطبيقات التي تريد تحديد البيئة (مكان UDF وغيره) أسلم لها توحيد التكوين على استدعاء EnsureCoreWebView2Async(env) صراحةً أوّلاً.

كذلك تُطلَق أحداث WebView2 كلّها على خيط واجهة المستخدم. كتابة معالجة ثقيلة (وصول أجهزة أو إدخال/إخراج ملفّات) مباشرة داخل WebMessageReceived تجمّد إحساس التشغيل في جانب الويب أيضاً، فأخرِج معالجة الجانب الأصليّ بـ async/await. المبادئ نفسها التي كتبناها في «خيط واجهة المستخدم وasync/await في WPF/WinForms» تنطبق هنا كما هي.

3. توزيع بيئة التشغيل ── Evergreen وFixed Version

3.1 Evergreen (موصى به)

Evergreen أسلوب تستخدم فيه جميع تطبيقات WebView2 بيئة تشغيل مشتركة مثبتة على العميل، وتُحدَّث بيئة التشغيل تلقائيّاً. توصي بها الجهة الرسميّة بوضوح لأنّ تصحيحات الأمان تُطبَّق تلقائيّاً واستهلاك القرص صغير.8

في العمل الفعليّ ثلاث نقاط انتباه.

  • نفِّذ فحص الوجود. مدمجة افتراضيّاً في Windows 11 وموزَّعة على نطاق واسع في Windows 10، ومع ذلك توجد «أجهزة بلاها». في .NET يمكن التحقّق بـ CoreWebView2Environment.GetAvailableBrowserVersionString()، لكن هذا الاستدعاء نفسه يفشل باستثناء (WebView2RuntimeNotFoundException) في بيئة بلا بيئة تشغيل، فغلِّفه بـ try/catch واحكم أنّ «الاستثناء = غير مثبت»، ثمّ انتقل في الإعداد إلى تشغيل bootstrapper (مثبِّت تمهيديّ صغير عبر الإنترنت) أو المثبِّت المستقلّ.2
  • صمِّم مواكبة تحديث بيئة التشغيل. حتّى بعد تحديث بيئة التشغيل يستمرّ التطبيق الجاري بالنسخة القديمة. النمط الموصى به التقاط حدث NewBrowserVersionAvailable وبناء مسار «يُطبَّق التحديث بعد إعادة التشغيل».2
  • واءِم مع ضبط التحديث الداخليّ. سياسة تحديث متصفّح Edge وسياسة تحديث بيئة تشغيل WebView2 شيئان مختلفان. في بيئة أوقفت تحديث بيئة التشغيل بسياسة المجموعة ينهار افتراض Evergreen (وجود الأحدث)، لذا عند استخدام واجهات أحدث أدخل اكتشاف الميزات.8

3.2 Fixed Version (استخدام محدود)

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

  • الثنائيّات المرفقة تتجاوز 250 ميغابايت فيكبر التوزيع بذلك المقدار2
  • بيئة التشغيل لا تُحدَّث تلقائيّاً، فتتحمّل مسؤوليّة توزيع إصلاحات ثغرات محرّك المتصفّح عبر إصداراتك
  • إهمال التحديث يُبقي داخل الشركة «تطبيق أعمال محمَّلاً بـ Chromium قديم»

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

4. أوّل مطبّ يُصادَف ── مجلد بيانات المستخدم

يحفظ WebView2 الكوكيز والتخزين المؤقّت والصلاحيّات وغيرها في مجلد بيانات المستخدم (UDF). إن لم تحدِّد مكان UDF يحاول الإنشاء في المكان الافتراضيّ (في كثير من التكوينات بجوار exe نفسه)، فتفشل الكتابة في التطبيقات المُثبَّتة تحت Program Files ويحدث خطأ تهيئة. يعمل على جهاز التطوير (تشغيل تصحيح، مجلّد قابل للكتابة) ويتوقّف فور التثبيت ── عطل نمطيّ «يُكتشف أوّل مرّة عند التوزيع».4

الإجراء بسيط: حدِّد دائماً مجلّداً مخصّصاً للتطبيق تحت %LOCALAPPDATA% كما في مثال الشيفرة السابق. وأدخل كذلك في التصميم ما يلي.

  • افصل UDF لكلّ مستخدم ولكلّ تطبيق (لا تشارك بين تطبيقات عدّة)
  • لا تضعه على قرص شبكيّ (يسبّب بطئاً وتلفاً وفقدان بيانات)4
  • قرِّر إجراء حذف UDF عند إلغاء التثبيت أو في وظيفة «مسح معلومات تسجيل الدخول» (إن لم يعرف المشغّل أنّ الكوكيز وبيانات المواقع تبقى هناك، يحدث تسرّب عند ترتيب أجهزة المغادرين مثلاً)

اعتبره نسخة WebView2 من مبدأ «لا تكتب بجوار exe» الذي كتبناه في المقال السابق «حفظ البيانات المحلّيّة لتطبيقات أعمال Windows».

5. تصميم التكامل بين الجزء الأصليّ والويب

ما يجعل WebView2 أكثر من «إطار متصفّح» هو التكامل المتبادل بين الشيفرة الأصليّة ومحتوى الويب. الوسائل الأساسيّة اثنتان.1

«أيّ جانب يرسل بأيّ واجهة ويستقبل بأيّ حدث» يختلط إن شُرح بالكلام فقط، فنضع أوّلاً صورة الذهاب والإياب كاملة. الشكل متناظر: الجانب الأصليّ يرسل بـ PostWebMessageAsJson ويستقبل بـ WebMessageReceived. جانب الويب يرسل بـ window.chrome.webview.postMessage ويستقبل بحدث message.

صفحة الويب (JavaScript)عنصر WebView2التطبيق المضيف (Native)صفحة الويب (JavaScript)عنصر WebView2التطبيق المضيف (Native)التهيئة: الاشتراك بعد اكتمال EnsureCoreWebView2Asyncيضغط المستخدم «طباعة الملصق»الاشتراك في WebMessageReceivedالاشتراك في message عبر window.chrome.webview.addEventListenerإرسال الطلب عبر window.chrome.webview.postMessageإطلاق WebMessageReceivedفحص المصدر عبر e.Source ومطابقة type بقائمة سماحتنفيذ معالجة أصليّة مثل التحكّم بالجهاز بشكل asyncإرسال النتيجة عبر PostWebMessageAsJsonإطلاق حدث messageتحديث عرض الحالة على الشاشة

النصف الأيسر أصليّ والنصف الأيمن ويب. النقطة وضع الفحص في موضع واحد فقط فور الاستقبال في الجانب الأصليّ، وبعد اجتيازه يمكن كتابة المعالجة بافتراض أنّ «الطلبات الواردة من type مسموح به فقط».

5.1 رسائل الويب (الشكل الأساسيّ)

يرسل الجانب الأصليّ JSON بـ PostWebMessageAsJson، ويستقبل جانب الويب بـ window.chrome.webview.addEventListener("message", ...). والاتّجاه المعاكس window.chrome.webview.postMessage(...) وحدث WebMessageReceived. الاقتران فضفاض، ويمكن فحص العمليّات المكشوفة في موضع واحد، لذا اجعل هذه الوسيلة الافتراضيّة للتكامل أوّلاً.

// ネイティブ → Web
webView.CoreWebView2.PostWebMessageAsJson(
    JsonSerializer.Serialize(new { type = "deviceStatus", connected = true }));

// Web → ネイティブ
webView.CoreWebView2.WebMessageReceived += (s, e) =>
{
    // 想定オリジン以外(外部サイトへ遷移した後など)からのメッセージは処理しない
    if (!e.Source.StartsWith("https://internal.example.co.jp/", StringComparison.Ordinal))
        return;

    AppMessage? msg;
    try { msg = JsonSerializer.Deserialize<AppMessage>(e.WebMessageAsJson); }
    catch (JsonException) { msg = null; }
    if (msg?.Type is null)
        return;  // 形式不正はここで捨てる(必要ならログへ)

    // type ごとに許可された操作だけを実行する
};

جانب الويب (JavaScript) يستقبل هكذا. لا تحتاج مكتبة خاصّة، بل تستخدم كائن window.chrome.webview الذي يحقنه WebView2.

// ネイティブからのメッセージを受け取る
window.chrome.webview.addEventListener("message", (e) => {
    if (e.data.type === "deviceStatus") {
        updateStatusBadge(e.data.connected);
    }
});

// ネイティブへ依頼を送る
document.getElementById("print-label").addEventListener("click", () => {
    window.chrome.webview.postMessage({ type: "printLabel", copies: 2 });
});

في جانب الاستقبال، كما في الشيفرة أعلاه، افحص أوّلاً e.Source (عنوان URI للصفحة التي أرسلت الرسالة)، ثمّ التزم بـ «فحص type الرسالة بقائمة سماح، وتجاهل غير المتوقَّع مع إبقاؤه في السجلّ». جانب الويب يمكن أن ينتقل إلى موقع خارجيّ برابط واحد أو إعادة توجيه واحدة، فلا تُسقط فحص المصدر بافتراض «ما يُعرض الآن صفحتي». وبالمقابل، إن وضعت في جانب الويب احتياطيّاً لحالة غياب window.chrome.webview (عند الفتح في متصفّح عاديّ)، صار بإمكانك تصحيح جزء واجهة الويب وحده في المتصفّح وارتفعت كفاءة التطوير.

5.2 كشف كائن المضيف (قويّ لكن محدود الاستخدام)

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

5.3 تحميل المحتوى المحلّيّ

عند إرفاق HTML/JS مع التطبيق وعرضه، الأسلوب المتعارف ليس القراءة المباشرة بـ file:// بل تعيين مجلّد إلى اسم مضيف افتراضيّ بـ SetVirtualHostNameToFolderMapping. يكتسب المحتوى أصلاً مثل https://appassets.example/، فتعمل واجهات ويب تفترض أصلاً مثل localStorage بشكل طبيعيّ، ويمكن تحديد مستوى السماح بالوصول عبر الأصول. استخدم للنطاق اسماً محجوزاً لا يُتوقَّع وجوده فعليّاً (مثل .example)، وابدأ نوع الوصول من الحدّ الأدنى الضروريّ (DenyCors أوّلاً).9

6. الخروج من وضع IE وWebView2 ── ActiveX لا يعمل

هذا أهمّ قسم في المقال. ما يُطيل عمر وضع IE هو أنّ IE11 الحقيقيّ (محرّك Trident) يعمل داخل Edge، فتعمل عناصر ActiveX وكائنات مساعدة المتصفّح كما هي.5 أمّا WebView2 فـ Chromium، ولا يملك آليّة لاستضافة ActiveX. أي أنّ خطّة الانتقال يجب أن تُبنى من القيد التالي:

«نقل نظام داخليّ يعمل في وضع IE إلى صدفة مصنوعة بـ WebView2» يصحّ فقط للشاشات غير المعتمِدة على ActiveX.

والترتيب الواقعيّ للانتقال كالتالي.

  1. الجرد: صنِّف صفحات وضع IE إلى «شاشات تستخدم تقنيّات خاصّة بـ IE مثل ActiveX» و«شاشات قديمة الصنع فقط» (إجراء الجرد في مقال وضع IE يُستخدَم كما هو. الخلاصة في سطر: عدِّد عناوين URL الخاضعة لوضع IE آليّاً عبر Enterprise Site Discovery، وصنِّف اعتماد كلّ عنوان إلى «وضع المستند» و«ActiveX / BHO» و«المصادقة» و«شهادة العميل» و«الملفّات والطباعة» و«الأجهزة وCOM»).
  2. الشاشات غير الخاصّة بـ IE: عدِّلها لدعم المتصفّحات الحديثة، واعرضها في Edge نفسه، أو احملها في صدفة WebView2 إن أردت دمجها في تطبيق طرفيّة الأعمال.
  3. شاشات اعتماد ActiveX: انقل الوظائف التي كان يتولّاها ActiveX (اتّصال تسلسليّ، وصول ملفّات، تحكّم بأجهزة مخصَّصة، إلخ) إلى الجانب الأصليّ (التطبيق المضيف لـ WebView2)، وأعد التصميم بحيث تُستدعى عبر رسائل الويب. الصورة قلب «ActiveX داخل المتصفّح» إلى «واجهة ويب داخل التطبيق + معالجة أصليّة».
  4. قرار الإبقاء على ActiveX نفسه أو تغليفه أو استبداله ينطبق عليه معيار «جدول قرار الإبقاء على ActiveX/OCX أو تغليفه أو استبداله» كما هو.

إعادة التصميم في الخطوة 3 هي حجم العمل الفعليّ لاعتماد WebView2، وضبط التوقّعات في مرحلة التخطيط ضروريّ: ليست قصّة بسيطة من نوع «أدخل WebView2 فتخرج من وضع IE». وبالمقابل، إذا اكتمل تصميم نقل وظائف ActiveX إلى التطبيق المضيف، صارت الواجهة أسهل صنعاً وصيانة بتقنيّة الويب، وبقي التوزيع تحت ضبط تطبيق سطح المكتب ── فتجمع الاثنين.

7. مسائل التنفيذ التي تُطرَح دائماً في الأنظمة الداخليّة

عند دراسة اعتماد WebView2 تظهر دائماً أسئلة من جانب الأعمال. نرتّبها استباقاً.

7.1 الطباعة والتقارير

متطلّب «في عهد IE كان زرّ الطباعة يُخرج التقرير» يمكن استقباله في WebView2 على مسارين.

  • طباعة الشاشة كما هي: إظهار حوار الطباعة بـ CoreWebView2.ShowPrintUI()، أو طباعة بلا مراقبة بـ PrintAsync. تعادل طباعة المتصفّح، فتعيينات طباعة CSS (@media print) تعمل كما هي.
  • الإخراج كـ PDF: يمكن إسقاط الصفحة المعروضة إلى ملفّ PDF بـ PrintToPdfAsync. لتدفّق أعمال من نوع «التقرير يُحفَظ PDF ويُوضَع في مجلّد مشترك» يناسب هذا المسار لأنّ الجانب الأصليّ يضبط اسم الملفّ ومكان الحفظ.1

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

7.2 تنزيل الملفّات ورفعها

التنزيل يعمل افتراضيّاً كما في المتصفّح، لكنّ الأسلوب في تطبيقات الأعمال التدخّل بحدث DownloadStarting. يمكن تثبيت مكان الحفظ، والسماح أو الرفض حسب الامتداد، وإخفاء واجهة التنزيل الافتراضيّة واستبدالها بإشعار من التطبيق.1 الرفع (<input type="file">) يفتح حوار اختيار ملفّات نظام التشغيل بلا تنفيذ خاصّ.

7.3 المصادقة وتسجيل الدخول الموحّد (SSO)

إن كان نظام الويب الداخليّ يعتمد مصادقة Windows المدمجة (NTLM/Kerberos)، يمرّ الأمر في WebView2 عموماً كما في المتصفّح. وفي الأنظمة القديمة التي تستخدم Basic يمكن توريد بيانات الاعتماد بحدث BasicAuthenticationRequested وتجاوز شاشة تسجيل الدخول ── غير أنّ مكان حفظ تلك البيانات هو بالضبط ما كتبناه في مقال DPAPI. إذا أردت تمرير SSO لـ Microsoft Entra ID (Azure AD سابقاً) بمعلومات تسجيل دخول نظام التشغيل، فانظر في تفعيل خيار البيئة AllowSingleSignOnUsingOSPrimaryAccount.

الكوكيز تُحفَظ في UDF، فتبقى حالة تسجيل الدخول بعد إعادة تشغيل التطبيق. إن أردت «محو الجلسة قطعاً بوظيفة تسجيل الخروج» فأدخل تنفيذاً يحذف صراحةً عبر CookieManager.

7.4 تصحيح الأخطاء أثناء التطوير

محتوى WebView2 هو Chromium، لذا تعمل أدوات المطوّر F12 كما هي أثناء التطوير (CoreWebView2Settings.AreDevToolsEnabled مفعَّل افتراضيّاً). طرق الفتح ثلاث: F12، وCtrl+Shift+I، والنقر الأيمن على الصفحة ثمّ «Inspect». حتّى إذا سددت الاختصارات وقائمة النقر الأيمن في بناء الإنتاج كما في الفصل 8، يمكن الفتح برمجيّاً من التطبيق عبر OpenDevToolsWindow (تجهيز «أدوات المطوّر من قائمة مخفيّة» للاستخدام الداخليّ يسهّل التحقيق على أجهزة الميدان دفعة واحدة).10

قبل الدخول في تنفيذ التكامل، التأكّد في ثلاث دقائق من أنّ الرسائل تذهب وتعود يقلّل الرجوع. بعد إدخال شيفرة 5.1 جرِّب بالترتيب التالي.

  1. شغِّل التطبيق، وافتح DevTools على شاشة WebView2 وانتقل إلى تبويب «Console».
  2. أدخل window.chrome.webview وقَيِّمه. ظهور كائن يعني أنّك داخل WebView2. إن ظهر undefined فاشكّ في انحراف افتراض: فتح في متصفّح عاديّ، أو عدم اكتمال التهيئة.
  3. أكّد الاتّجاه ويب ← أصليّ. نفِّذ في وحدة التحكّم window.chrome.webview.postMessage({ type: "printLabel", copies: 1 })، وإن وضعت نقطة توقّف في معالج WebMessageReceived في الجانب الأصليّ توقّف هناك. تأكّد أنّ e.WebMessageAsJson يحمل JSON نفسه وأنّ e.Source يحمل عنوان URI للصفحة الحاليّة.
  4. أكّد الاتّجاه أصليّ ← ويب. سجِّل في وحدة التحكّم window.chrome.webview.addEventListener("message", e => console.log(e.data)) ثمّ نفِّذ عمليّة تستدعي PostWebMessageAsJson في الجانب الأصليّ (قائمة، تغيّر حالة جهاز، إلخ) فيظهر JSON في وحدة التحكّم.

إذا أكّدت بهذه الأربع أنّ «يمكن الإرسال والاستقبال والمصدر كما هو متوقَّع»، بقي العمل إضافة معالجة لكلّ type. وزيادة على ذلك، إن بنيت جانب واجهة الويب بحيث «يعمل أيضاً في المتصفّح وحده» كما سبق، أمكن إدارة تطوير الواجهة وتصحيحها كتطوير ويب عاديّ، وقصر التحقّق من التكامل الأصليّ على WebView2. أي أنّ حبس أصول الويب داخل التطبيق لا يمنع الإبقاء على تجربة التطوير كتجربة ويب.

8. نقاط أساسيّة في تصميم الأمان

تطبيق WebView2 «تطبيق فيه متصفّح مضمَّن»، فكِّر بنموذج تهديد يعادل المتصفّح.

  • قيِّد المحتوى المعروض: افحص وجهة الانتقال في NavigationStarting بقائمة سماح لنطاقات داخليّة، ومرِّر العناوين غير المتوقَّعة إلى المتصفّح الافتراضيّ (وعالج NewWindowRequested بالمثل).
  • ضيِّق الوظائف التي تعبر حدود الثقة: نطاق كشف كائن المضيف، والعمليّات المسموحة عبر رسائل الويب، في الحدّ الأدنى. ومن المفيد أيضاً فصل WebView قد يعرض مواقع خارجيّة عن WebView يملك تكاملاً أصليّاً.
  • اضبط وظائف المستخدم وفق البيئة: تتيح CoreWebView2Settings الإبقاء على «طابع المتصفّح» بالقدر اللازم فقط. تضييقها في أجهزة الأكشاك وأجهزة الميدان يقلّل الحوادث.
  • إن كانت Fixed Version فتحمّل مسؤوليّة خطّة التحديث: كما سبق، توزيع إصلاح الثغرات واجب جانب التطبيق.8

نذكر بنوداً تُضبَط كثيراً في CoreWebView2Settings. يُستحسَن إدراج كيف تكون في بناء الإنتاج ضمن قائمة التحقّق قبل الإصدار.

الإعداد الافتراضيّ النمط النموذجيّ في أجهزة الميدان والإنتاج
AreDevToolsEnabled (أدوات المطوّر F12) مفعَّل يُعطَّل في الإنتاج
AreDefaultContextMenusEnabled (قائمة النقر الأيمن) مفعَّل يُعطَّل في الشاشات التي لا يُراد فيها «رجوع» و«إعادة تحميل»
AreBrowserAcceleratorKeysEnabled (اختصارات مثل Ctrl+F5) مفعَّل يُعطَّل في استخدام الأكشاك
IsStatusBarEnabled (عرض وجهة الرابط) مفعَّل حسب التفضيل
IsZoomControlEnabled (تكبير Ctrl+العجلة) مفعَّل يُعطَّل في شاشات الأعمال التي ينهار تخطيطها
AreHostObjectsAllowed (كائنات المضيف) مفعَّل يُعطَّل إن لم تُستخدَم

ليست هذه «أماناً بالتعطيل» بقدر ما هي أدوات «لإغلاق مداخل غير العمليّات التي قصدها التطبيق». لرفع أمان تطبيقات Windows عموماً راجع أيضاً «قائمة التحقّق الدنيا لأمان تطبيقات Windows».

9. ترتيب قرار الاعتماد

التكوين المشاهد المناسبة نقاط الانتباه
العرض في Edge (المتصفّح) نظام ويب داخليّ عاديّ لا دمج تطبيقيّ ولا تكامل أصليّ
تطبيق قائم + WebView2 لجزء من واجهة الويب تحديث شاشة بشاشة، إعادة استخدام أصول الويب UDF وتوزيع بيئة التشغيل وتصميم التكامل (هذا المقال)
صدفة WebView2 + نقل الوظائف الأصليّة مخرج أصول وضع IE المعتمِدة على ActiveX إعادة تنفيذ وظائف ActiveX هي الجوهر
Electron ونظائره عند وجوب عبور المنصّات ثقيل إن كان Windows فقط. يزيد التوزيع والذاكرة
إعادة البناء أصليّاً بالكامل (WPF وغيره) لا أصول ويب، أو افتراض عدم الاتّصال يُوازَن بتكلفة التطوير

إن كان المراد «تطبيق داخليّ خاصّاً بـ Windows يستخدم واجهة بتقنيّة الويب»، فالخيار الافتراضيّ WebView2 لا Electron. المشاركة مع بيئة التشغيل في جانب نظام التشغيل تخفّف التوزيع، والدمج مع أصول .NET القائمة مستقيم.

10. الخلاصة

WebView2 تقنيّة متوافقة مع تحديث الأنظمة الداخليّة، تتيح تضمين واجهة ويب قائمة على Chromium كمكوّن في تطبيق Windows. نقاط العمل عند الإدخال ثلاث: فحص وجود بيئة Evergreen ومواكبة التحديث، وتحديد مجلد بيانات المستخدم صراحةً، وتصميم تكامل أساسه رسائل الويب. وعلى صعيد التخطيط: مواجهة قيد أنّ ActiveX لا يعمل، وجعل إعادة التصميم التي تنقل وظائف ActiveX إلى الجانب الأصليّ مركز حجم العمل.

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

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

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

تتعامل شركة كومورا سوفت ذ.م.م. مع تصميم مخرج الأنظمة الداخليّة المعتمِدة على وضع IE وActiveX، والتحديث المتدرّج باستخدام WebView2، واستشارات دمج واجهة ويب في تطبيقات Windows القائمة.

المراجع

  1. Microsoft Learn, Overview of WebView2 APIs. حول الصورة الكاملة لوظائف WebView2 بما فيها إدارة التنقّل، وتحميل المحتوى المحلّيّ، والتواصل بين المضيف والويب (رسائل الويب، كائنات المضيف).  2 3 4 5

  2. Microsoft Learn, Distribute your app and the WebView2 Runtime. حول التوزيع عبر bootstrapper / المثبِّت المستقلّ، وكشف التثبيت، ومواكبة التحديث عبر NewBrowserVersionAvailable، وإجراء إرفاق Fixed Version (أكثر من 250 ميغابايت).  2 3 4

  3. Microsoft Learn, Evergreen vs. fixed version of the WebView2 Runtime. حول الفرق بين نمطي توزيع بيئة التشغيل، والإدماج الافتراضيّ في Windows 11، ومزايا Fixed Version وعيوبها.  2 3

  4. Microsoft Learn, Manage user data folders. حول دور مجلد بيانات المستخدم، وصلاحيّات القراءة والكتابة اللازمة لـ UDF مخصّص، وكون وضعه على قرص شبكيّ سبباً لبطء وانهيار وفقدان بيانات.  2 3

  5. Microsoft Learn, What is Internet Explorer (IE) mode?. حول عمل وضع IE بمحرّك Trident (MSHTML) ودعمه لعناصر ActiveX وكائنات مساعدة المتصفّح (أي أنّ WebView2 القائم على Chromium لا يملك هذا الدعم).  2

  6. Microsoft Learn, Introduction to Microsoft Edge WebView2. حول عملاء Windows التي تعمل عليها تطبيقات WebView2 (Windows 10 SAC 1709 فما فوق، إصدارات LTSC / IoT Enterprise، Windows 11) وWindows Server (LTSC لـ 2016 / 2019 / 2022، وSAC)، وبيئات التطوير المدعومة (Win32 C/C++، .NET Framework 4.6.2 فما فوق، .NET Core 3.1 فما فوق، .NET 5 فما فوق، WinUI 2.0 / 3.0)، وإمكان الاستخدام أيضاً على Xbox وHoloLens 2.  2 3 4

  7. Microsoft Learn, Get started with WebView2 in WinForms apps. حول اشتراط Visual Studio 2017 فما فوق واستثناء Visual Studio Code من الدرس، وإضافة SDK Microsoft.Web.WebView2 لكلّ مشروع عبر NuGet، وترتيب التهيئة بالاشتراك في WebMessageReceived بعد اكتمال EnsureCoreWebView2Async، والتواصل المتبادل عبر window.chrome.webview.postMessage وPostWebMessageAsString / PostWebMessageAsJson 2

  8. Microsoft Learn, Development best practices for WebView2 apps. حول التوصية بـ Evergreen، والتعامل مع تحديث بيئة التشغيل، واكتشاف الميزات، وضرورة التحديث الدوريّ عند استخدام Fixed Version.  2 3

  9. Microsoft Learn, Using local content in WebView2 apps. حول تحميل المحتوى المحلّيّ بتعيين اسم مضيف افتراضيّ، ومزيّة اكتساب أصل، وتحديد نوع الوصول (DenyCors وغيره). 

  10. Microsoft Learn, Debug WebView2 apps with Microsoft Edge DevTools. حول طرق فتح DevTools الثلاث: F12، وCtrl+Shift+I، والنقر الأيمن على الصفحة ثمّ «Inspect»، وإمكان الفتح برمجيّاً بواجهة OpenDevToolsWindow إذا حُذفت الاختصارات أو قائمة النقر الأيمن. 

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

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

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

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

هل يعمل ActiveX داخل WebView2؟
لا يعمل. يعمل وضع IE داخل Edge بمحرّك IE11 الحقيقيّ (محرّك Trident)، لذا يعمل ActiveX كما هو، أمّا WebView2 فقائم على Chromium ولا يملك آليّة لاستضافة ActiveX. لذلك لا يمكن الاكتفاء بـ«نقل الشاشات المعتمِدة على ActiveX إلى WebView2» فحسب، بل يلزم نقل الوظائف التي كان يتولّاها ActiveX (كالاتّصال التسلسليّ، والوصول إلى الملفّات، والتحكّم بالأجهزة المخصَّصة) إلى الجانب الأصليّ (التطبيق المضيف)، وإعادة تصميمها بحيث تُستدعى عبر رسائل الويب. وإعادة التصميم هذه بالذات هي حجم العمل الفعليّ لاعتماد WebView2.
أيّهما ينبغي اختياره لبيئة تشغيل WebView2، Evergreen أم Fixed Version؟
المبدأ الأساسيّ هو Evergreen (بيئة تشغيل مشتركة تُحدَّث تلقائيّاً)، وتوصي بها الجهة الرسميّة بوضوح لأنّ تصحيحات الأمان تُطبَّق تلقائيّاً واستهلاك القرص صغير. مدمجة افتراضيّاً في Windows 11، لكن توجد أجهزة لم تُثبَّت فيها بعد، لذا يُدمَج فحص الوجود وbootstrap (مثبِّت تمهيديّ صغير عبر الإنترنت) في المُثبِّت. أمّا Fixed Version (المُرفَقة مع التطبيق) فيتجاوز حجمها المُرفَق 250 ميغابايت، وتتحمَّل الجهة مسؤوليّة توزيع إصلاحات ثغرات محرّك المتصفّح عبر إصداراتها الخاصّة، لذا ينبغي اختيارها فقط في حالات محدودة كأجهزة التصنيع غير المتّصلة بالإنترنت أو البيئات ذات إدارة التغيير الصارمة.
لماذا لا يُشغَّل تطبيق WebView2 بعد التثبيت؟
المطبّ النموذجيّ الأوّل هو مشكلة مجلد بيانات المستخدم (User Data Folder، اختصاراً UDF). يحفظ WebView2 الكوكيز والتخزين المؤقّت والصلاحيّات في UDF، لكن إن لم يُحدَّد موقعه، يحاول افتراضيّاً إنشاءه بجوار ملفّ الـ exe، فتفشل الكتابة في التطبيقات المُثبَّتة تحت Program Files ويحدث خطأ في التهيئة. هذا عطل نموذجيّ يعمل على جهاز التطوير لكن يتوقّف فور التثبيت. الحلّ هو تحديد مجلد مخصّص للتطبيق تحت %LOCALAPPDATA% صراحةً دوماً عند إنشاء CoreWebView2Environment. كما يجب تجنّب وضعه على قرص شبكيّ لأنّ ذلك يسبِّب بطئاً وتلفاً في البيانات.
كيف يتكامل الكود الأصليّ مع صفحة الويب في WebView2؟
الأساس هو التكامل الفضفاض عبر رسائل الويب. يرسل الجانب الأصليّ JSON عبر PostWebMessageAsJson، ويستقبله جانب الويب عبر حدث message الخاصّ بـ window.chrome.webview. أمّا الاتّجاه المعاكس فعبر postMessage وحدث WebMessageReceived. من المهمّ في جانب الاستقبال فحص عنوان URI المصدر عبر e.Source، وفحص نوع (type) الرسالة عبر قائمة سماح. توجد أيضاً طريقة لكشف كائنات .NET/COM مباشرةً عبر AddHostObjectToScript، لكن نظراً لضخامة الأثر عند اختراق الصفحة، ينبغي قصرها على المحتوى الذي تديره الشركة نفسها، وتقليص الطرق المكشوفة إلى الحدّ الأدنى الضروريّ.

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

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

غو كومورا

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

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

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