После IE-режима — WebView2? Ограничение по ActiveX и реалистичный план миграции

· · WebView2, Windows, .NET, WPF, WinForms, Режим IE, ActiveX, Миграция устаревших систем, Внутренние системы, Техническая консультация

В предыдущей статье «Как продлить жизнь внутренней веб-системе, зависящей от IE-режима, и как из него выйти» я писал, что IE-режим — это лишь временная мера с ограниченным сроком действия и что параллельно с ним стоит проектировать выход. И когда к нам обращаются именно с вопросом об этом «выходе», очень часто всплывает WebView2. «Хотим показать внутреннюю веб-систему внутри специализированного приложения», «хотим сделать web-технологиями только часть экранов desktop-приложения», «слышали, что Electron тяжёлый, — есть ли альтернатива?» — во всех этих случаях WebView2 оказывается одним из вариантов.

При этом у WebView2 есть особенности, которые нужно понимать до внедрения: как распространять среду выполнения, куда класть папку пользовательских данных, как заставить нативную сторону и веб-сторону обмениваться данными. И, что важнее всего, есть ограничение, напрямую влияющее на план миграции: ActiveX, работавший в IE-режиме, в WebView2 не работает. В этой статье разберём базовую архитектуру WebView2, распространение, проектирование, безопасность и то, как всё это реалистично сочетается с выходом из IE-режима.

1. Сначала вывод

  • WebView2 — это элемент управления, встраивающий Chromium-версию Microsoft Edge в Windows-приложение. Его можно использовать из WinForms / WPF / WinUI / Win32 C++, и он хорошо подходит для того, чтобы добавить «немного Web UI» к уже существующему desktop-приложению. 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

2. Базовая архитектура WebView2

WebView2 состоит из двух частей: «SDK» (API, встраиваемый в приложение) и «среда выполнения» (исполняющая среда на основе Edge, устанавливаемая на клиентской машине). Это та же схема, что и у Visual C++ Runtime или .NET Runtime: приложение собирается со ссылкой на NuGet-пакет Microsoft.Web.WebView2, а во время выполнения использует среду выполнения, установленную на клиенте. 3

Поддерживаемые платформы широки: можно использовать из WinForms и WPF на .NET Framework 4.6.2+ / .NET Core 3.1+, из WinUI, из Win32 C++. Большое преимущество перед подходом, требующим смены всего фреймворка целиком (как, например, Electron), — возможность поэтапного использования: перевести на WebView2 только один экран уже существующего WinForms-приложения. О выборе самого UI-фреймворка см. также «Как выбрать между WinForms, WPF и WinUI — таблица решений».

Минимальное встраивание выглядит примерно так (идея общая для 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.

Здесь стоит сразу отметить одну важную особенность API: webView.CoreWebView2 равен null, пока инициализация не завершена. Классическая ошибка — попытка подписаться на событие вроде CoreWebView2.WebMessageReceived += ... в конструкторе формы, что приводит к NullReferenceException. Базовый подход — сосредоточить всю работу, зависящую от инициализации, в блоке «после await EnsureCoreWebView2Async». Присвоение свойству Source тоже неявно запускает инициализацию, но в приложениях, где нужно указать параметры среды (например, расположение UDF), безопаснее унифицировать код так, чтобы EnsureCoreWebView2Async(env) вызывался явно и заранее.

Кроме того, все события WebView2 срабатывают в UI-потоке. Если написать тяжёлую операцию (доступ к оборудованию, файловый ввод-вывод) прямо внутри WebMessageReceived, вместе с ней замрёт и отзывчивость веб-стороны, поэтому обработку на нативной стороне нужно выносить через async/await. Эти принципы прямо описаны в статье «UI-поток и async/await в WPF/WinForms — памятка на одну страницу».

3. Распространение среды выполнения — Evergreen и Fixed Version

3.1 Evergreen (рекомендуется)

Evergreen — это модель, при которой все приложения на WebView2 используют общую среду выполнения, установленную на клиенте, и она обновляется автоматически. Microsoft явно рекомендует именно её, потому что патчи безопасности применяются автоматически, а расход дискового пространства невелик. 6

На практике важны три момента.

  • Реализовать проверку наличия. В Windows 11 она встроена по умолчанию, широко распространена и на Windows 10, но устройства без неё всё же встречаются. В .NET проверить можно через CoreWebView2Environment.GetAvailableBrowserVersionString(), но на машине без установленной среды выполнения сам этот вызов завершится исключением (WebView2RuntimeNotFoundException), поэтому его нужно оборачивать в try/catch, трактовать исключение как «не установлено» и встраивать в установку переход к запуску bootstrap-инсталлятора (небольшого онлайн-инсталлятора) или автономного инсталлятора. 2
  • Спроектировать отслеживание обновлений среды выполнения. Даже после обновления среды выполнения уже запущенное приложение продолжает использовать старую версию. Рекомендуемый паттерн — перехватывать событие NewBrowserVersionAvailable и выстраивать сценарий вида «после перезапуска обновление вступит в силу». 2
  • Согласовать с внутренней политикой обновлений организации. Политика обновления браузера Edge и политика обновления среды выполнения WebView2 — разные вещи. В средах, где групповая политика останавливает обновление среды выполнения, базовое предположение Evergreen («установлена последняя версия») перестаёт выполняться, поэтому при использовании более новых API стоит добавлять определение поддерживаемых возможностей (feature detection). 6

3.2 Fixed Version (ограниченное применение)

Fixed Version — это способ поставки конкретной версии среды выполнения вместе с приложением. Он позволяет зафиксировать проверенную конфигурацию, что разумно для офлайн-производственного оборудования или сред со строгим контролем изменений. Однако у него есть весомая цена:

  • поставляемые бинарные файлы весят более 250 МБ, и на столько же увеличивается дистрибутив; 2
  • поскольку среда выполнения не обновляется автоматически, вы берёте на себя ответственность за распространение исправлений уязвимостей браузерного движка через собственные релизы;
  • если пренебречь обновлениями, в компании продолжает жить «рабочее приложение со старым Chromium внутри».

Выбирайте этот вариант только в тех случаях, когда отображаемый контент полностью закрыт и находится под вашим собственным управлением, а процесс релизов позволяет включать обновления среды выполнения.

4. Первая ловушка — папка пользовательских данных

WebView2 хранит cookie, кэш и разрешения в папке пользовательских данных (UDF). Если не указать её расположение, по умолчанию она пытается создаться в стандартном месте (в большинстве конфигураций — рядом с exe-файлом), поэтому у приложения, установленного в Program Files, запись туда завершится ошибкой, а инициализация упадёт. На машине разработчика (отладочный запуск, папка с правом записи) всё работает, но стоит установить приложение — и оно перестаёт запускаться: типичная ошибка, «обнаруживающаяся только после поставки». 4

Решение простое — как в примере кода выше, всегда явно указывать выделенную папку приложения внутри %LOCALAPPDATA%. Заодно стоит заложить в проект и следующее:

  • разделять UDF по пользователю и по приложению (не использовать общую папку для нескольких приложений);
  • не размещать её на сетевом диске (это приводит к падению скорости, повреждению и потере данных); 4
  • заранее определить процедуру удаления UDF при деинсталляции или через функцию «очистить данные входа» (если оператор не знает, что именно там хранятся cookie и данные сайта, это легко упустить, например, при очистке машины уволившегося сотрудника).

Считайте это версией для WebView2 принципа «не писать рядом с exe-файлом», описанного в статье «Где хранить локальные данные в корпоративном Windows-приложении — таблица решений».

5. Проектирование связи нативной стороны с Web

То, что превращает WebView2 из «просто рамки браузера» в нечто большее, — это двустороннее взаимодействие нативного кода с веб-контентом. Есть в основном два механизма. 1

5.1 Web-сообщения (базовый вариант)

Нативная сторона отправляет 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 отсутствует (то есть страница открыта в обычном браузере) — это позволяет отлаживать веб-часть UI автономно, в обычном браузере, что повышает эффективность разработки.

5.2 Публикация host-объекта (мощно, но с ограниченным применением)

AddHostObjectToScript позволяет вызывать .NET/COM-объект напрямую из JavaScript. Внутри это устроено через механизм COM, и забавно видеть, что технология COM, с которой мы работаем уже давно, до сих пор актуальна и в такой ситуации. Но напрямую отдавать нативный объект веб-контенту означает, что при компрометации страницы последствия оказываются гораздо серьёзнее. Публикацию стоит ограничивать контентом, которым вы управляете сами, а набор публичных методов сводить к необходимому минимуму. Базовое правило — не регистрировать host-объекты в WebView, где может отображаться недоверенная страница.

5.3 Загрузка локального контента

Если HTML/JS поставляются вместе с приложением, стандартный подход — не читать их напрямую через file://, а сопоставить папку виртуальному имени хоста через SetVirtualHostNameToFolderMapping. Поскольку у контента появляется origin вида https://appassets.example/, обычным образом работают web API, зависящие от origin, такие как localStorage, а также можно задать уровень разрешения кросс-доменного доступа. Для имени хоста стоит использовать заведомо несуществующий зарезервированный домен (например, .example), а тип доступа начинать с минимально необходимого (сначала DenyCors). 7

6. Выход из IE-режима и WebView2 — ActiveX не работает

Это самый важный раздел статьи. IE-режим держится на плаву потому, что внутри Edge работает настоящий IE11 (движок Trident), и элементы ActiveX и Browser Helper Object работают в нём как обычно. 5 WebView2, напротив, построен на Chromium и не имеет механизма для хостинга ActiveX. Иными словами,

«перенести внутреннюю систему, работающую в IE-режиме, на оболочку из WebView2» работает только для экранов, не зависящих от ActiveX.

Именно из этого ограничения нужно выстраивать план миграции. Реалистичный порядок миграции выглядит так:

  1. Инвентаризация: разделить страницы, зависящие от IE-режима, на «экраны, использующие специфичные для IE технологии вроде ActiveX» и «экраны, которые просто сделаны по-старому» (для этого напрямую подходит подход к инвентаризации списка сайтов из статьи об IE-режиме).
  2. Экраны без специфики IE: доработать под современные браузеры и либо отображать прямо в Edge, либо, если нужна интеграция в приложение рабочего места, встроить в оболочку WebView2.
  3. Экраны, зависящие от ActiveX: перепроектировать так, чтобы функциональность, которую раньше выполнял ActiveX (последовательная связь, доступ к файлам, управление специализированным оборудованием и т. п.), переехала на нативную сторону (хост-приложение WebView2) и вызывалась через web-сообщения. Это можно представить как переворот схемы «ActiveX внутри браузера» в схему «Web UI внутри приложения + нативная обработка».
  4. Решение о том, оставлять ли сам ActiveX, оборачивать его или заменять, можно принимать по тем же критериям, что и в статье «Оставить, обернуть или заменить ActiveX/OCX — таблица решений».

Именно этот редизайн из пункта 3 составляет реальный объём работ по внедрению WebView2, и на этапе планирования нужно скорректировать ожидания: это не так просто, как «установить WebView2 и выйти из IE-режима». С другой стороны, если довести до конца проектирование переноса функциональности ActiveX на хост-приложение, можно получить сразу оба преимущества: UI, который проще разрабатывать и сопровождать своими силами на web-технологиях, и распространение, которое по-прежнему контролируется как у desktop-приложения.

7. Вопросы по реализации, которые обязательно возникают для внутренних систем

При рассмотрении WebView2 со стороны бизнеса неизбежно возникает ряд вопросов. Разберём их заранее.

7.1 Печать и отчёты

Требование «в IE по кнопке печати выводился отчёт» в WebView2 можно закрыть двумя способами.

  • Печать экрана как есть: вызвать диалог печати через CoreWebView2.ShowPrintUI() либо напечатать без участия пользователя через PrintAsync. Это эквивалентно печати из браузера, поэтому правила печати в CSS (@media print) применяются точно так же.
  • Вывод в PDF: PrintToPdfAsync позволяет сохранить отображаемую страницу в PDF-файл. Для бизнес-процесса вида «сохранить отчёт в PDF и положить в общую папку» этот способ подходит лучше, поскольку имя файла и место сохранения можно контролировать на нативной стороне. 1

Для отчётов, требующих попиксельной точности выравнивания колонок (например, бланков с копировальной прокладкой), стоит рассмотреть и вариант с выводом отчёта на нативной стороне (подход, описанный в статье «Как построить вывод Excel-отчётов»), вместо того чтобы добиваться нужного результата через печать из браузера.

7.2 Скачивание и загрузка файлов

Скачивание по умолчанию работает так же, как в браузере, но в корпоративном приложении стандартной практикой является вмешательство через событие DownloadStarting. Оно позволяет зафиксировать место сохранения, разрешать или запрещать по расширению файла, а также убрать стандартный UI скачивания в пользу собственного уведомления приложения. 1 Загрузка (<input type="file">) открывает системный диалог выбора файла без какой-либо специальной реализации.

7.3 Аутентификация и SSO

Если внутренняя веб-система использует встроенную аутентификацию Windows (NTLM/Kerberos), в WebView2 она в целом проходит так же, как в браузере. Для старых систем с Basic-аутентификацией учётные данные можно передавать через событие BasicAuthenticationRequested, минуя показ экрана входа, — но вопрос о том, где хранить эти учётные данные, как раз относится к теме статьи о DPAPI. Если нужно, чтобы SSO Microsoft Entra ID (бывший Azure AD) проходило через данные входа в ОС, стоит рассмотреть включение параметра среды AllowSingleSignOnUsingOSPrimaryAccount.

Cookie хранятся в UDF, поэтому состояние входа сохраняется даже после перезапуска приложения. Если нужна функция выхода, гарантированно очищающая сессию, добавьте явное удаление cookie через CookieManager.

7.4 Отладка во время разработки

Поскольку внутри WebView2 работает Chromium, во время разработки доступны обычные DevTools по F12 (CoreWebView2Settings.AreDevToolsEnabled включён по умолчанию). А если, как упоминалось выше, сделать веб-часть UI так, чтобы она работала и автономно, «в чистом браузере», разработку и отладку UI можно вести как обычную web-разработку, а на WebView2 проверять только нативную интеграцию. То есть даже когда веб-ресурсы заперты внутри приложения, опыт разработки остаётся привычным веб-опытом.

8. Ключевые моменты проектирования безопасности

Приложение на WebView2 — это «приложение со встроенным браузером», поэтому и модель угроз стоит рассматривать по аналогии с браузером.

  • Ограничить отображаемый контент: в NavigationStarting проверять адрес перехода по белому списку внутренних доменов, а всё непредусмотренное отправлять в браузер по умолчанию (аналогично обрабатывать и NewWindowRequested).
  • Сузить функциональность, пересекающую границу доверия: минимизировать область публикации host-объектов и операции, разрешённые через web-сообщения. Полезно также разделять WebView, который может отображать внешние сайты, и WebView с нативной интеграцией.
  • Настраивать пользовательские функции под конкретную среду: CoreWebView2Settings позволяет оставить ровно столько «браузерности», сколько нужно. На киосках и рабочих терминалах стоит их урезать — это снижает число инцидентов.
  • При использовании Fixed Version — взять на себя ответственность за план обновлений: как уже говорилось, распространение исправлений уязвимостей в этом случае становится обязанностью самого приложения. 6

Ниже — параметры CoreWebView2Settings, которые чаще всего настраивают. Что делать с ними в production-сборке, стоит включить в чек-лист перед релизом.

Параметр По умолчанию Типичное значение для рабочих терминалов / production
AreDevToolsEnabled (инструменты разработчика по F12) Включено В production отключают
AreDefaultContextMenusEnabled (контекстное меню по правой кнопке) Включено Отключают на экранах, где не должны использоваться «Назад» и «Обновить»
AreBrowserAcceleratorKeysEnabled (сочетания клавиш вроде Ctrl+F5) Включено Отключают для киоск-сценариев
IsStatusBarEnabled (отображение адреса ссылки) Включено По желанию
IsZoomControlEnabled (масштабирование Ctrl+колесо) Включено Отключают на бизнес-экранах, где от масштабирования ломается вёрстка
AreHostObjectsAllowed (host-объекты) Включено Отключают, если не используются

Все эти параметры — не столько про «отключил и стало безопасно», сколько про «закрыть любые входы, кроме тех операций, которые предусмотрены приложением». Общее повышение уровня безопасности Windows-приложений разобрано в статье «Минимальный чек-лист безопасности Windows-приложения».

9. Итог по выбору решения

Конфигурация Подходит для На что обратить внимание
Отображение в Edge (браузер) Обычная внутренняя веб-система Интеграция в приложение и нативная связь невозможны
Существующее приложение + WebView2 для части экранов Модернизация по отдельным экранам, повторное использование веб-ресурсов UDF, распространение среды выполнения, проектирование связи (эта статья)
Оболочка WebView2 + перенос нативной функциональности Выход из ActiveX-зависимых активов IE-режима Основная работа — реализация функциональности ActiveX заново
Electron и подобные Когда кроссплатформенность обязательна Тяжеловесно, если нужен только Windows. Больше дистрибутив, больше памяти
Полностью нативная переработка (WPF и т. п.) Нет веб-ресурсов / расчёт на офлайн Соотносить со стоимостью разработки

Если нужно «внутреннее приложение только под Windows с UI на web-технологиях», по умолчанию стоит выбирать WebView2, а не Electron. Поскольку среда выполнения общая с ОС, дистрибутив получается легче, а интеграция с существующими .NET-ресурсами — прямолинейной.

10. Заключение

WebView2 — технология, позволяющая встроить в Windows-приложение Web UI на основе Chromium как отдельный компонент, и она хорошо сочетается с модернизацией внутренних систем. Практические моменты при внедрении сводятся к трём: проверка наличия среды выполнения Evergreen и отслеживание её обновлений, явное указание папки пользовательских данных, а также проектирование связи по умолчанию через web-сообщения. А на уровне планирования — прямо смотреть на ограничение «ActiveX не работает» и ставить в центр оценки трудозатрат редизайн, переносящий функциональность ActiveX на нативную сторону.

Если, поглядывая на срок действия IE-режима, вы уже думаете «пора бы заняться выходом», надёжнее всего начать с инвентаризации целевой системы и декомпозиции функциональности, зависящей от ActiveX. Многое здесь трудно оценить без взгляда на реальную конфигурацию системы, так что если сомневаетесь — обращайтесь для консультации.

Похожие статьи

Смежные области консультаций

Komura Software Co., Ltd. занимается консультациями по проектированию выхода для внутренних систем, зависящих от IE-режима и ActiveX, поэтапной модернизации с помощью WebView2 и интеграции Web UI в существующие Windows-приложения.

Источники

  1. Microsoft Learn, Overview of WebView2 APIs. Об общей картине возможностей WebView2: управление навигацией, загрузка локального контента, связь хоста с Web (web-сообщения, host-объекты).  2 3 4 5

  2. Microsoft Learn, Distribute your app and the WebView2 Runtime. О распространении через bootstrap-инсталлятор/автономный инсталлятор, определении уже установленной версии, отслеживании обновлений через NewBrowserVersionAvailable и процедуре включения Fixed Version (более 250 МБ).  2 3 4

  3. Microsoft Learn, Evergreen vs. fixed version of the WebView2 Runtime. О различиях двух моделей распространения среды выполнения, встроенной поставке в Windows 11, а также о плюсах и минусах Fixed Version.  2

  4. Microsoft Learn, Manage user data folders. О роли папки пользовательских данных, правах на чтение и запись, необходимых для собственной UDF, а также о том, почему размещение на сетевом диске приводит к падению скорости, сбоям и потере данных.  2 3

  5. Microsoft Learn, What is Internet Explorer (IE) mode?. О том, что IE-режим работает на движке Trident (MSHTML) и поддерживает элементы ActiveX и Browser Helper Object (то есть у построенного на Chromium WebView2 такой поддержки нет).  2

  6. Microsoft Learn, Development best practices for WebView2 apps. О рекомендации использовать Evergreen, работе с обновлениями среды выполнения, определении поддерживаемых возможностей и необходимости регулярных обновлений при использовании Fixed Version.  2 3

  7. Microsoft Learn, Using local content in WebView2 apps. О загрузке локального контента через сопоставление виртуального имени хоста, преимуществах наличия origin и указании типа доступа (например, DenyCors). 

Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.

Значки в области уведомлений и всплывающие (toast) уведомления в Windows-приложениях — подводные камни NotifyIcon и выбор правильного AppNotification

Практическое руководство о том, как удерживать бизнес-приложение Windows в области уведомлений (system tray) и оповещать пользователя с п...

Эти страницы показывают тему статьи в более широком контексте услуг и решений.

Статья напрямую связана со следующими услугами.

Частые вопросы

Вопросы, которые часто возникают при консультациях по теме статьи.

Работает ли ActiveX в WebView2?
Нет. IE-режим держится именно потому, что внутри Edge работает настоящий IE11 (движок Trident), где ActiveX функционирует как обычно, а WebView2 построен на Chromium и не имеет механизма для хостинга ActiveX. Поэтому «перенести систему, зависящую от IE-режима, на оболочку WebView2» работает только для экранов, которые не зависят от ActiveX. Для остальных экранов функциональность, которую раньше выполнял ActiveX, — последовательная связь, доступ к файлам, управление специализированным оборудованием — нужно перенести на нативную сторону (хост-приложение) и вызывать через web-сообщения. Именно этот редизайн и составляет основной объём работ при внедрении WebView2.
Какую среду выполнения WebView2 выбрать — Evergreen или Fixed Version?
По умолчанию — Evergreen (общая среда выполнения с автоматическим обновлением): патчи безопасности применяются автоматически, а расход дискового пространства невелик, поэтому Microsoft прямо рекомендует именно этот вариант. В Windows 11 она встроена по умолчанию, но поскольку не на всех устройствах она установлена, в инсталлятор стоит встроить проверку наличия и bootstrap. Fixed Version (среда выполнения, поставляемая вместе с приложением) весит более 250 МБ и возлагает на вас ответственность за распространение исправлений уязвимостей самого браузерного движка через собственные релизы, поэтому её стоит выбирать только в ограниченных случаях — например, для офлайн-производственного оборудования или сред со строгим контролем изменений.
Почему приложение на WebView2 не запускается после установки?
Первая типичная проблема — папка пользовательских данных (UDF). WebView2 хранит в ней cookie, кэш и разрешения, и если не указать её расположение явно, по умолчанию она пытается создаться рядом с exe-файлом. Поэтому у приложения, установленного в Program Files, запись туда завершится ошибкой, и инициализация упадёт. Классическая ситуация: на машине разработчика всё работает, а после установки — нет. Решение — всегда явно указывать выделенную папку приложения внутри %LOCALAPPDATA% при создании CoreWebView2Environment. Размещать её на сетевом диске тоже не стоит — это приводит к падению скорости и повреждению данных.
Как нативный код и веб-страница взаимодействуют в WebView2?
Базовый способ — слабосвязанный обмен через web-сообщения. С нативной стороны JSON отправляется через PostWebMessageAsJson, а веб-сторона получает его через событие message объекта window.chrome.webview. В обратном направлении используются postMessage и событие WebMessageReceived. На стороне получателя важно сначала проверить источник сообщения через e.Source, а затем проверить type сообщения по белому списку. Есть и способ напрямую предоставить .NET/COM-объект через AddHostObjectToScript, но последствия компрометации страницы в этом случае гораздо серьёзнее, поэтому его стоит ограничивать контентом, которым вы управляете сами, и сводить набор публичных методов к минимуму.

Об авторе

Страница с профилем автора статьи.

Го Комура

Представитель KomuraSoft LLC

Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.

Публичные ссылки

Вернуться в блог