En un artículo anterior, «Cómo prolongar la vida de un sistema Web interno dependiente del modo IE y cómo salir de él», escribimos que el modo IE es solo una medida de prolongación con fecha de caducidad y que conviene diseñar la salida en paralelo. Cuando recibimos consultas sobre esa «salida», WebView2 aparece con mucha frecuencia. «Queremos mostrar el sistema Web interno dentro de una aplicación dedicada», «queremos construir solo una pantalla de la aplicación de escritorio con tecnología Web», «hemos oído que Electron es pesado, ¿hay alguna alternativa?»: en todos estos casos, WebView2 entra en la lista de opciones.
Por otro lado, WebView2 tiene una serie de peculiaridades que conviene conocer antes de adoptarlo: cómo distribuir el runtime, dónde colocar la carpeta de datos de usuario, cómo hacer que el lado nativo y el lado Web se comuniquen. Y, sobre todo, existe una restricción que afecta al núcleo de cualquier plan de migración: el ActiveX que funcionaba en el modo IE no funciona en WebView2. En este artículo repasamos la estructura básica de WebView2, la distribución, el diseño, la seguridad, y cómo combinarlo de forma realista con la salida del modo IE.
1. Primero, la conclusión
- WebView2 es un control que incrusta el Microsoft Edge basado en Chromium en una aplicación de Windows. Se puede usar desde WinForms, WPF, WinUI y Win32 C++, y resulta adecuado para añadir «solo una parte con Web UI» a una aplicación de escritorio ya existente.1
- Como runtime se usa, en principio, Evergreen (el runtime compartido que se actualiza automáticamente). Windows 11 lo incluye de serie, pero en lugar de dar por hecho que «debería estar instalado», la recomendación oficial es incorporar en el instalador una comprobación de presencia y un bootstrap.2
- Para entornos sin conexión o fábricas/líneas de producción que necesitan fijar una configuración validada existe Fixed Version (incluido con la aplicación), pero los binarios superan los 250 MB y usted asume la responsabilidad de distribuir las actualizaciones de seguridad por su cuenta. No lo elija a la ligera.3
- El primer tropiezo suele ser la carpeta de datos de usuario (UDF). Por defecto se crea junto al ejecutable, así que una aplicación instalada bajo Program Files falla al arrancar. Convierta en norma indicar explícitamente una carpeta bajo
%LOCALAPPDATA%.4 - La comunicación nativo⇔Web se basa fundamentalmente en el intercambio de mensajes mediante
PostWebMessageAsJson/WebMessageReceived, yAddHostObjectToScript(exposición de objetos COM) debe limitarse a contenido de confianza.1 - Dentro de WebView2, ActiveX no funciona. No es posible «simplemente trasladar a WebView2» una página dependiente del modo IE que incluya ActiveX; hace falta un diseño que traslade al lado nativo el procesamiento que ActiveX realizaba. Este es el núcleo de cualquier plan de salida del modo IE.5
2. Estructura básica de WebView2
WebView2 se compone de dos piezas: el «SDK» (la API que se incorpora a la aplicación) y el «runtime» (el entorno de ejecución basado en Edge que se instala en el cliente). Es la misma lógica que el runtime de Visual C++ o el de .NET: la aplicación se compila referenciando el paquete NuGet Microsoft.Web.WebView2, y en tiempo de ejecución utiliza el runtime instalado en el cliente.3
El abanico de plataformas compatibles es amplio: se puede usar desde WinForms y WPF en .NET Framework 4.6.2 o posterior / .NET Core 3.1 o posterior, desde WinUI y desde Win32 C++. Poder adoptarlo de forma gradual —por ejemplo, convertir a WebView2 solo una pantalla de una aplicación de negocio existente en WinForms— es una gran ventaja frente a los enfoques que obligan a cambiar de framework por completo (como Electron). Para la elección del propio framework de UI, consulte también la «Tabla de decisión WinForms / WPF / WinUI».
Reunimos aquí, tal como figuran en la documentación oficial, los requisitos previos que siempre se preguntan al principio de cualquier evaluación.
| Elemento | Contenido |
|---|---|
| SO cliente compatible | Windows 10 (SAC 1709 o posterior), las distintas LTSC / IoT Enterprise de Windows 10, Windows 116 |
| SO servidor compatible | Windows Server 2016 / 2019 / 2022 (LTSC), Windows Server (SAC)6 |
| Entornos de desarrollo compatibles | Win32 C/C++, .NET Framework 4.6.2 o posterior, .NET Core 3.1 o posterior, .NET 5 o posterior, WinUI 2.0 / 3.06 |
| IDE | Visual Studio 2017 o posterior. El tutorial oficial indica explícitamente que Visual Studio Code no está cubierto7 |
| SDK | Paquete NuGet Microsoft.Web.WebView2 (se añade por proyecto)7 |
| Necesario en tiempo de ejecución | El runtime de WebView2. En principio, Evergreen; Windows 11 lo incluye de serie (capítulo 3)3 |
| Dispositivos que no son Windows | También se puede usar en Xbox y HoloLens 26 |
La integración mínima queda así en código (el planteamiento es común a WPF y WinForms).
var env = await CoreWebView2Environment.CreateAsync(
browserExecutableFolder: null, // Usar el runtime 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/");
El punto clave es que no se deja el valor por defecto: CoreWebView2Environment se crea explícitamente. La razón se explica en los dos próximos capítulos.
El propio procedimiento de introducción es sencillo; en WinForms / WPF sigue este flujo.
- Añadir
Microsoft.Web.WebView2al proyecto mediante NuGet (el control WebView2 también aparecerá en el cuadro de herramientas del diseñador). - Colocar el control en el formulario o la ventana.
- Inicializar con
EnsureCoreWebView2Async, como en el código anterior, y después llamar aNavigate.
Aquí hay un detalle de la API que conviene tener claro desde el principio: webView.CoreWebView2 es null hasta que termina la inicialización. Un tropiezo clásico es intentar suscribirse a un evento como CoreWebView2.WebMessageReceived += ... en el constructor del formulario y obtener un NullReferenceException; la forma básica es concentrar todo el procesamiento relacionado con la inicialización «después del await de EnsureCoreWebView2Async». Asignar a la propiedad Source inicia la inicialización de forma implícita, pero en aplicaciones que necesitan especificar el entorno (por ejemplo, la ubicación de la UDF) es más seguro unificar el diseño llamando primero, de forma explícita, a EnsureCoreWebView2Async(env).
Además, todos los eventos de WebView2 se disparan en el hilo de UI. Si se escribe directamente dentro de WebMessageReceived un procesamiento pesado (acceso a dispositivos, E/S de archivos), la sensación de uso del lado Web también se queda congelada de rebote, así que el procesamiento del lado nativo debe delegarse con async/await. Los principios que expusimos en «El hilo de UI y async/await en WPF/WinForms» se aplican aquí tal cual.
3. Distribución del runtime — Evergreen y Fixed Version
3.1 Evergreen (recomendado)
Evergreen es el modelo en el que todas las aplicaciones WebView2 usan el runtime compartido instalado en el cliente, y ese runtime se actualiza automáticamente. Microsoft lo recomienda explícitamente porque los parches de seguridad se aplican solos y el consumo de disco es menor.8
En la práctica hay tres puntos de atención.
- Implemente una comprobación de presencia. Windows 11 lo incluye de serie y también se ha distribuido ampliamente a Windows 10, pero aun así existen equipos donde no está instalado. En .NET se puede comprobar con
CoreWebView2Environment.GetAvailableBrowserVersionString(), pero en un entorno sin el runtime instalado, esa misma llamada falla con una excepción (WebView2RuntimeNotFoundException), así que hay que envolverla en try/catch, interpretar «excepción = no instalado» e incorporarlo a la instalación pasando a ejecutar un bootstrapper (un instalador en línea pequeño) o un instalador independiente.2 - Diseñe cómo seguir las actualizaciones del runtime. Aunque el runtime se actualice, la aplicación que ya está en ejecución sigue usando la versión antigua. El patrón recomendado es capturar el evento
NewBrowserVersionAvailabley preparar un flujo del tipo «al reiniciar se aplica la actualización».2 - Alinéelo con la gestión de actualizaciones interna de la empresa. La política de actualización del navegador Edge y la del runtime de WebView2 son cosas distintas. En entornos donde la directiva de grupo detiene las actualizaciones del runtime, la premisa de Evergreen (que siempre está la última versión) deja de cumplirse, así que si va a usar API relativamente nuevas, incorpore detección de funcionalidades.8
3.2 Fixed Version (uso limitado)
Fixed Version es el modelo en el que se incluye con la aplicación una versión concreta del runtime. Como permite congelar una configuración ya validada, resulta una elección razonable en equipos de fabricación sin conexión o en entornos con una gestión de cambios muy estricta. Sin embargo,
- los binarios incluidos superan los 250 MB, por lo que el paquete de distribución crece en esa medida,2
- como el runtime no se actualiza automáticamente, usted asume la responsabilidad de distribuir en sus propias versiones las correcciones de vulnerabilidades del motor del navegador,
- si se descuidan las actualizaciones, quedan circulando en la empresa «aplicaciones de negocio con un Chromium antiguo dentro».
Son contrapartidas importantes. Elija Fixed Version únicamente cuando el contenido que se muestra sea completamente cerrado y gestionado por la propia empresa, y cuando exista una estructura capaz de incorporar la actualización del runtime al ciclo de publicación.
4. La primera trampa habitual — la carpeta de datos de usuario
WebView2 guarda las cookies, la caché y los permisos, entre otras cosas, en la carpeta de datos de usuario (UDF, user data folder). Si no se especifica la ubicación de la UDF, intenta crearla en la ubicación por defecto (en muchas configuraciones, justo al lado del ejecutable), por lo que en una aplicación instalada bajo Program Files la escritura falla y se produce un error de inicialización. Es un fallo típico que «solo se descubre al distribuir»: funciona en la máquina de desarrollo (ejecución en depuración, carpeta con permisos de escritura), pero deja de funcionar en cuanto se instala.4
La solución es sencilla: como en el ejemplo de código anterior, hay que indicar siempre de forma explícita una carpeta propia de la aplicación bajo %LOCALAPPDATA%. Conviene incluir también en el diseño lo siguiente.
- Separe la UDF por usuario y por aplicación (no la comparta entre varias aplicaciones).
- No la coloque en una unidad de red (provoca lentitud, corrupción y pérdida de datos).4
- Defina de antemano el procedimiento para eliminar la UDF al desinstalar o mediante una función de «borrar información de inicio de sesión» (si el personal de operaciones no sabe que ahí quedan cookies y datos del sitio, se filtra información, por ejemplo, al limpiar el equipo de alguien que deja la empresa).
Considérelo la versión para WebView2 del principio «no escribir junto al ejecutable» que expusimos en el artículo anterior «Almacenamiento de datos locales en aplicaciones Windows de negocio».
5. Diseño de la comunicación entre nativo y Web
Lo que convierte a WebView2 en algo más que «un simple marco de navegador» es la comunicación mutua entre el código nativo y el contenido Web. Existen principalmente dos mecanismos.1
Explicar con palabras «quién envía con qué API y quién recibe con qué evento» tiende a confundir, así que primero mostramos el panorama completo del ida y vuelta. Es una estructura simétrica: el lado nativo envía con PostWebMessageAsJson y recibe con WebMessageReceived. El lado Web envía con window.chrome.webview.postMessage y recibe con el evento message.
sequenceDiagram
participant N as Lado nativo Aplicación host
participant W as Control WebView2
participant P as Página Web JavaScript
Note over N,P: Inicialización: suscribirse tras completarse EnsureCoreWebView2Async
N->>W: Se suscribe a WebMessageReceived
P->>W: Se suscribe a message con window.chrome.webview.addEventListener
Note over P: El usuario pulsa "Imprimir etiqueta"
P->>W: Envía la solicitud con window.chrome.webview.postMessage
W->>N: Se dispara WebMessageReceived
N->>N: Verifica el origen con e.Source y compara el type contra la lista blanca
N->>N: Ejecuta el procesamiento nativo (control de dispositivo, etc.) de forma async
N->>W: Envía el resultado con PostWebMessageAsJson
W->>P: Se dispara el evento message
P->>P: Actualiza el estado mostrado en pantalla
La mitad izquierda del diagrama es el lado nativo, y la mitad derecha, el lado Web. El punto clave es colocar la verificación en un único lugar, justo después de la recepción en el lado nativo; el procesamiento posterior a ese punto se puede escribir asumiendo que «solo llegan solicitudes con un type permitido».
5.1 Mensajes Web (forma básica)
Desde el lado nativo se envía JSON con PostWebMessageAsJson, y el lado Web lo recibe con window.chrome.webview.addEventListener("message", ...). En sentido inverso se usan window.chrome.webview.postMessage(...) y el evento WebMessageReceived. Al estar débilmente acoplado y permitir verificar en un único punto las operaciones que se exponen, este debe ser el mecanismo de comunicación por defecto.
// Nativo → Web
webView.CoreWebView2.PostWebMessageAsJson(
JsonSerializer.Serialize(new { type = "deviceStatus", connected = true }));
// Web → Nativo
webView.CoreWebView2.WebMessageReceived += (s, e) =>
{
// No procesar mensajes que no vengan del origen esperado (por ejemplo, tras navegar a un sitio externo)
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; // Descartar aquí los mensajes con formato inválido (registrar en el log si hace falta)
// Ejecutar solo las operaciones permitidas según el type
};
El lado Web (JavaScript) lo recibe así. No hace falta ninguna librería especial; basta con usar el objeto window.chrome.webview que inyecta WebView2.
// Recibir mensajes del lado nativo
window.chrome.webview.addEventListener("message", (e) => {
if (e.data.type === "deviceStatus") {
updateStatusBadge(e.data.connected);
}
});
// Enviar una solicitud al lado nativo
document.getElementById("print-label").addEventListener("click", () => {
window.chrome.webview.postMessage({ type: "printLabel", copies: 2 });
});
En el lado receptor, como en el código anterior, verifique primero e.Source (el URI de la página que envió el mensaje) y, a partir de ahí, sea estricto en «comprobar el type del mensaje contra una lista blanca, ignorar lo inesperado y dejarlo registrado en el log». El lado Web puede pasar a un sitio externo con un solo enlace o una sola redirección, así que no omita la verificación del origen dando por supuesto que «lo que se muestra ahora tiene que ser mi propia página». A la inversa, si en el lado Web también incorpora un mecanismo de reserva para cuando window.chrome.webview no existe (por ejemplo, si se abre en un navegador normal), podrá depurar la parte de UI Web por sí sola en el navegador, lo que mejora la eficiencia del desarrollo.
5.2 Exposición de objetos host (potente pero de uso limitado)
Con AddHostObjectToScript es posible llamar directamente objetos .NET/COM desde JavaScript. Internamente se apoya en el mecanismo de COM, y resulta curioso ver a la tecnología COM que llevamos tanto tiempo tratando seguir vigente en un lugar así; pero dejar que el contenido Web tenga acceso directo a un objeto nativo significa que el impacto también es mayor si esa página se ve comprometida. Limite lo que expone a contenido gestionado por la propia empresa y reduzca al mínimo imprescindible los métodos expuestos. El principio es no registrarlo en ningún WebView que pueda llegar a mostrar páginas no confiables.
5.3 Carga de contenido local
Cuando se incluye HTML/JS en la aplicación para mostrarlo, la práctica habitual no es leerlo directamente con file://, sino mapear una carpeta a un nombre de host virtual con SetVirtualHostNameToFolderMapping. Como el contenido obtiene así un origen del tipo https://appassets.example/, las API Web que dan por hecho un origen, como localStorage, funcionan con normalidad, y también se puede especificar el nivel de permiso para el acceso entre orígenes. Use como nombre de host un dominio reservado que no pueda existir en la realidad (como .example) y empiece con el tipo de acceso mínimo necesario (primero DenyCors).9
6. La salida del modo IE y WebView2 — ActiveX no funciona
Esta es la sección más importante del artículo. El modo IE puede prolongar la vida de un sistema porque dentro de Edge se ejecuta un IE11 real (el motor Trident), gracias a lo cual ActiveX y los Browser Helper Objects funcionan tal cual.5 WebView2, en cambio, es Chromium y no tiene ningún mecanismo para alojar ActiveX. Es decir,
«Trasladar un sistema interno que funciona en modo IE a una carcasa hecha con WebView2» solo es válido para las pantallas que no dependen de ActiveX.
El plan de migración debe construirse a partir de esta restricción. El orden de migración realista es el siguiente.
- Inventario: clasifique las páginas dependientes del modo IE en «pantallas que usan tecnología específica de IE, como ActiveX» y «pantallas que simplemente están hechas de forma antigua» (puede usar tal cual el procedimiento de inventario del artículo sobre el modo IE. Resumido en una línea: enumerar mecánicamente con Enterprise Site Discovery las URL sujetas al modo IE y clasificar la dependencia de cada URL en «modo de documento», «ActiveX / BHO», «autenticación», «certificado de cliente», «archivos e impresión» y «equipos y COM»).
- Pantallas que no son específicas de IE: modifíquelas para que funcionen en un navegador moderno y muéstrelas en el propio Edge, o llévelas a una carcasa WebView2 si necesita integrarlas en la aplicación del equipo de trabajo.
- Pantallas dependientes de ActiveX: rediseñe las funciones que ActiveX cubría (comunicación serie, acceso a archivos, control de equipos dedicados, etc.) trasladándolas al lado nativo (la aplicación host de WebView2) e invocándolas a través de mensajes Web. Es la imagen de invertir «ActiveX dentro del navegador» en «UI Web dentro de la aplicación + procesamiento nativo».
- Para decidir si conserva el propio ActiveX, lo envuelve o lo sustituye, puede aplicar tal cual los criterios de la «tabla de decisión para mantener, envolver o sustituir ActiveX/OCX».
El rediseño del punto 3 es, en la práctica, el esfuerzo real que supone adoptar WebView2, y en la fase de planificación hace falta ajustar expectativas: no es tan simple como decir que «con instalar WebView2 basta para salir del modo IE». Dicho de otro modo, en cuanto el diseño para trasladar las funciones de ActiveX a la aplicación host esté terminado, se obtienen las dos ventajas a la vez: la UI se vuelve más fácil de desarrollar y mantener internamente con tecnología Web, y la distribución se puede gobernar como la de una aplicación de escritorio.
7. Cuestiones de implementación que siempre surgen en sistemas internos
Al evaluar la adopción de WebView2, siempre surgen del lado del negocio algunas preguntas. Las organizamos aquí de antemano.
7.1 Impresión y formularios
El requisito de «con IE, el botón de imprimir sacaba el formulario» se puede cubrir en WebView2 mediante dos vías.
- Imprimir la pantalla tal cual: mostrar el diálogo de impresión con
CoreWebView2.ShowPrintUI(), o imprimir sin intervención conPrintAsync. Al ser equivalente a la impresión del navegador, las directivas de impresión CSS (@media print) funcionan tal cual. - Exportar como PDF: con
PrintToPdfAsyncse puede volcar la página que se está mostrando a un archivo PDF. Para el flujo de negocio de «guardar el formulario como PDF en una carpeta compartida», esta opción es más adecuada, porque permite controlar desde el lado nativo el nombre de archivo y el destino de guardado.1
En formularios como los albaranes multicopia que exigen un alineamiento a nivel de píxel, considere también la opción de recurrir a la salida de formularios del lado nativo (el método que expusimos en «Cómo construir formularios de Excel») en lugar de forzarlo con la impresión Web.
7.2 Descarga y carga de archivos
La descarga funciona igual que en un navegador incluso por defecto, pero en aplicaciones de negocio la práctica habitual es intervenir con el evento DownloadStarting. Con él se puede aplicar control: fijar el destino de guardado, permitir o rechazar según la extensión, o sustituir la UI de descarga por defecto por una notificación propia de la aplicación.1 La carga (<input type="file">) abre el diálogo de selección de archivos del sistema operativo sin necesidad de ninguna implementación especial.
7.3 Autenticación y SSO
Si el sistema Web interno usa autenticación integrada de Windows (NTLM/Kerberos), en WebView2 también pasa, en general, igual que en un navegador. En sistemas antiguos que usan autenticación Basic, se pueden suministrar las credenciales con el evento BasicAuthenticationRequested, lo que permite evitar incluso mostrar la pantalla de inicio de sesión; ahora bien, dónde guardar esas credenciales es, precisamente, el tema del artículo sobre DPAPI. Si quiere que el SSO de Microsoft Entra ID (antes Azure AD) pase con la información de inicio de sesión del sistema operativo, considere habilitar la opción de entorno AllowSingleSignOnUsingOSPrimaryAccount.
Como las cookies se guardan en la UDF, el estado de inicio de sesión se mantiene aunque se reinicie la aplicación. Si quiere que la función de cierre de sesión elimine la sesión de forma fiable, incorpore una implementación que la borre explícitamente con CookieManager.
7.4 Depuración durante el desarrollo
Como por dentro WebView2 es Chromium, durante el desarrollo se puede usar tal cual el DevTools con F12 (CoreWebView2Settings.AreDevToolsEnabled está habilitado por defecto). Hay tres formas de abrirlo: F12, Ctrl+Shift+I y hacer clic derecho en la página y elegir «Inspeccionar». Incluso si, como en el capítulo 8, bloquea el atajo y el menú contextual en la compilación de producción, puede abrirlo mediante programación llamando a OpenDevToolsWindow desde la aplicación (si prepara para uso interno un «acceso a las herramientas de desarrollo desde un menú oculto», investigar los equipos sobre el terreno se vuelve mucho más sencillo).10
Antes de entrar en la implementación de la comunicación, comprobar en tres minutos que los mensajes van y vienen reduce el retrabajo. Con el código del apartado 5.1 ya incorporado, pruebe en este orden.
- Inicie la aplicación, abra el DevTools en la pantalla de WebView2 y pase a la pestaña «Consola».
- Escriba
window.chrome.webviewy evalúelo. Si aparece un objeto, se está ejecutando dentro de WebView2. Si saleundefined, sospeche de un desajuste de premisas, como que se ha abierto en un navegador normal o que la inicialización aún no ha terminado. - Compruebe Web → Nativo. Ejecute en la consola
window.chrome.webview.postMessage({ type: "printLabel", copies: 1 }), y si coloca un punto de interrupción en el manejadorWebMessageReceiveddel lado nativo, la ejecución se detendrá ahí. Compruebe quee.WebMessageAsJsoncontiene el mismo JSON y quee.Sourcecontiene el URI de la página actual. - Compruebe Nativo → Web. Tras registrar en la consola
window.chrome.webview.addEventListener("message", e => console.log(e.data)), realice una operación que llame aPostWebMessageAsJsonen el lado nativo (un menú, un cambio de estado de un dispositivo, etc.) y verá el JSON aparecer en la consola.
Si con estos cuatro pasos ha podido confirmar que «se puede enviar, se puede recibir y el origen es el esperado», lo que queda es simplemente ir añadiendo el procesamiento para cada type. Además, como se mencionó antes, si construye el lado de la UI Web de modo que «también funcione solo en el navegador», puede repartir el trabajo: el desarrollo y la depuración de la UI se llevan como un desarrollo Web normal, y solo la comunicación nativa se verifica sobre WebView2. En otras palabras, aunque los activos Web queden encerrados dentro de la aplicación, la experiencia de desarrollo se mantiene igual que en la Web.
8. Puntos clave del diseño de seguridad
Una aplicación WebView2 es, en esencia, «una aplicación con un navegador incorporado», así que hay que pensar con un modelo de amenazas equivalente al de un navegador.
- Limite el contenido que se muestra: verifique el destino de navegación con
NavigationStartingcontra una lista blanca de dominios internos, y redirija al navegador por defecto las URL inesperadas (proceseNewWindowRequestedde la misma manera). - Reduzca las funciones que cruzan el límite de confianza: mantenga al mínimo el alcance de los objetos host expuestos y las operaciones permitidas mediante mensajes Web. También ayuda separar el WebView que puede mostrar sitios externos del WebView que tiene comunicación nativa.
- Ajuste las funciones orientadas al usuario según el entorno: con
CoreWebView2Settingspuede conservar «el aspecto de navegador» solo en la medida necesaria. Restringirlo en quioscos y equipos de campo reduce los incidentes. - Con Fixed Version, asuma la responsabilidad del plan de actualizaciones: como se mencionó antes, distribuir las correcciones de vulnerabilidades pasa a ser responsabilidad de la aplicación.8
A continuación, los elementos que se ajustan con frecuencia en CoreWebView2Settings. Se recomienda incluir en la checklist previa a la publicación qué hacer con cada uno en la compilación de producción.
| Ajuste | Valor por defecto | Uso típico en producción / equipos de campo |
|---|---|---|
AreDevToolsEnabled (herramientas de desarrollo F12) |
Habilitado | Deshabilitar en producción |
AreDefaultContextMenusEnabled (menú contextual del botón derecho) |
Habilitado | Deshabilitar en pantallas donde no se quiera permitir «Atrás» ni «Recargar» |
AreBrowserAcceleratorKeysEnabled (atajos como Ctrl+F5) |
Habilitado | Deshabilitar en uso de quiosco |
IsStatusBarEnabled (mostrar el destino del enlace) |
Habilitado | Según preferencia |
IsZoomControlEnabled (zoom con Ctrl+rueda) |
Habilitado | Deshabilitar en pantallas de negocio donde el zoom rompe el diseño |
AreHostObjectsAllowed (objetos host) |
Habilitado | Deshabilitar si no se usan |
En todos los casos, más que «deshabilitarlo es seguro», son herramientas para «cerrar las entradas que no forman parte de la operación prevista de la aplicación». Para elevar la seguridad general de las aplicaciones Windows, consulte también la «checklist mínima de seguridad para aplicaciones Windows».
9. Resumen para decidir la adopción
| Configuración | Escenario adecuado | Puntos de atención |
|---|---|---|
| Mostrarlo en Edge (navegador) | Un sistema Web interno normal | No permite integración con la aplicación ni comunicación nativa |
| Aplicación existente + WebView2 para parte de la UI Web | Modernización pantalla a pantalla, reutilización de activos Web | UDF, distribución del runtime, diseño de la comunicación (este artículo) |
| Carcasa WebView2 + traslado de funciones nativas | Salida de activos del modo IE dependientes de ActiveX | Reimplementar las funciones de ActiveX es el grueso del trabajo |
| Electron y similares | Cuando es imprescindible el soporte multiplataforma | Pesado si es solo para Windows; aumenta el tamaño distribuido y la memoria |
| Reconstruir en modo totalmente nativo (WPF, etc.) | Sin activos Web, entorno pensado para trabajar sin conexión | Hay que sopesarlo frente al coste de desarrollo |
Si lo que se busca es «una aplicación interna exclusiva de Windows en la que se quiera usar una UI hecha con tecnología Web», WebView2 es la opción por defecto, por delante de Electron. Al poder compartir el runtime con el sistema operativo, la distribución es más ligera, y la integración con los activos .NET existentes también resulta natural.
10. Resumen
WebView2 es una tecnología que permite incorporar como pieza, dentro de una aplicación Windows, una UI Web basada en Chromium, y encaja bien con la modernización de sistemas internos. Los puntos prácticos al adoptarlo son tres: comprobar la presencia del runtime Evergreen y seguir sus actualizaciones, indicar de forma explícita la carpeta de datos de usuario, y diseñar la comunicación tomando como base los mensajes Web. Y, en el plano de la planificación, hay que afrontar de frente la restricción de que ActiveX no funciona y situar en el centro del esfuerzo el rediseño que traslada las funciones de ActiveX al lado nativo.
Si, con la fecha límite del modo IE en el horizonte, está pensando que «ya va siendo hora de buscar una salida», lo más sólido es empezar por hacer inventario del sistema en cuestión y por descomponer en funciones la parte dependiente de ActiveX. Hay muchos aspectos de este proceso que son difíciles de decidir sin ver la configuración real del sistema, así que si tiene dudas, no dude en consultarnos.
Artículos relacionados
- Cómo prolongar la vida de un sistema Web interno dependiente del modo IE y cómo salir de él
- Cómo tratar hoy ActiveX / OCX - tabla de decisión para mantener, envolver o sustituir
- Qué son COM, ActiveX y OCX
- Cómo elegir entre WinForms/WPF/WinUI - tabla de decisión práctica
Áreas de consultoría relacionadas
En KomuraSoft LLC atendemos consultas sobre el diseño de la salida de sistemas internos dependientes del modo IE y de ActiveX, la modernización gradual mediante WebView2, y la integración de UI Web en aplicaciones Windows ya existentes.
- Aprovechamiento y migración de activos existentes
- Reemplazo de aplicaciones Windows
- Consultoría técnica y revisión de diseño
- Contacto
Referencias
-
Microsoft Learn, Overview of WebView2 APIs. Sobre la gestión de la navegación, la carga de contenido local y la comunicación host⇔Web (mensajes Web, objetos host), entre otras funciones que conforman el panorama completo de WebView2. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Distribute your app and the WebView2 Runtime. Sobre la distribución mediante bootstrapper o instalador independiente, la detección de instalaciones existentes, el seguimiento de actualizaciones con NewBrowserVersionAvailable, y el procedimiento para incluir Fixed Version (más de 250 MB). ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Evergreen vs. fixed version of the WebView2 Runtime. Sobre la diferencia entre los dos modelos de distribución del runtime, su inclusión de serie en Windows 11, y las ventajas e inconvenientes de Fixed Version. ↩ ↩2 ↩3
-
Microsoft Learn, Manage user data folders. Sobre el papel de la carpeta de datos de usuario, los permisos de lectura y escritura necesarios para una UDF personalizada, y el hecho de que colocarla en una unidad de red provoca lentitud, bloqueos y pérdida de datos. ↩ ↩2 ↩3
-
Microsoft Learn, What is Internet Explorer (IE) mode?. Sobre el hecho de que el modo IE funciona con el motor Trident (MSHTML) y admite controles ActiveX y Browser Helper Objects (es decir, algo que WebView2, basado en Chromium, no admite). ↩ ↩2
-
Microsoft Learn, Introduction to Microsoft Edge WebView2. Sobre los clientes Windows en los que funcionan las aplicaciones WebView2 (Windows 10 SAC 1709 o posterior, las distintas LTSC / IoT Enterprise, Windows 11) y Windows Server (2016 / 2019 / 2022 LTSC, SAC), los entornos de desarrollo compatibles (Win32 C/C++, .NET Framework 4.6.2 o posterior, .NET Core 3.1 o posterior, .NET 5 o posterior, WinUI 2.0 / 3.0), y el hecho de que también se puede usar en Xbox y HoloLens 2. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Get started with WebView2 in WinForms apps. Sobre la necesidad de Visual Studio 2017 o posterior y que Visual Studio Code queda fuera del alcance del tutorial, la incorporación del SDK
Microsoft.Web.WebView2por proyecto mediante NuGet, el orden de inicialización en el queWebMessageReceivedse suscribe después de que se completeEnsureCoreWebView2Async, y la comunicación mutua mediantewindow.chrome.webview.postMessageyPostWebMessageAsString/PostWebMessageAsJson. ↩ ↩2 -
Microsoft Learn, Development best practices for WebView2 apps. Sobre la recomendación de Evergreen, el tratamiento de las actualizaciones del runtime, la detección de funcionalidades, y la necesidad de actualizaciones periódicas al usar Fixed Version. ↩ ↩2 ↩3
-
Microsoft Learn, Using local content in WebView2 apps. Sobre la carga de contenido local mediante el mapeo de nombres de host virtuales, las ventajas de que se le asigne un origen, y la especificación del tipo de acceso (como DenyCors). ↩
-
Microsoft Learn, Debug WebView2 apps with Microsoft Edge DevTools. Sobre las tres formas de abrir el DevTools (F12, Ctrl+Shift+I, y hacer clic derecho en la página y elegir «Inspeccionar»), y el hecho de que, si se eliminan el atajo y el menú contextual, se puede abrir mediante programación con la API
OpenDevToolsWindow. ↩
Artículos relacionados
Artículos recientes con las mismas etiquetas para profundizar en temas cercanos.
Integrar la autenticación de Entra ID en aplicaciones WinForms/WPF — Configuración práctica con MSAL.NET y el bróker WAM
Cómo integrar Entra ID en apps WinForms/WPF: cliente público, registro de la app, AcquireTokenSilent, bróker WAM y persistencia de la cac...
Compatibilidad de WPF con alto DPI ── causas y soluciones del desenfoque pese a que «debería ser resistente al DPI»
WPF es System DPI Aware, pero al moverse a un monitor con otro DPI toda la ventana se difumina y los mapas de bits se ven borrosos. Repas...
Externalización y desarrollo por encargo de una app Windows: qué aclarar antes de solicitarlo
Antes de encargar la externalización o el desarrollo por encargo de una app Windows, estos son los puntos a aclarar: revisión de software...
Iconos de la bandeja del sistema y notificaciones toast en aplicaciones Windows — los escollos de NotifyIcon y cómo elegir el AppNotification adecuado
Organiza la implementación de la residencia en la bandeja del sistema y las notificaciones toast en aplicaciones Windows empresariales: e...
Internacionalización de aplicaciones WinForms/WPF — la práctica de resx, ensamblados satélite y el cambio de cultura
Organizamos la internacionalización de aplicaciones de escritorio Windows: la diferencia entre CurrentCulture y CurrentUICulture, el meca...
Temas relacionados
Estas páginas sitúan el tema en un contexto más amplio de servicios y decisiones.
Temas técnicos de Windows
Portal sobre desarrollo de Windows, investigación de fallos y aprovechamiento de activos existentes.
Migración de ActiveX
Decisiones para conservar, encapsular o sustituir componentes COM / ActiveX / OCX.
Hilo de UI y temporizadores
Hilo de UI de WPF / WinForms, flujos asíncronos, Dispatcher y diseño de temporizadores.
Servicios relacionados con este tema
El artículo está directamente relacionado con los siguientes servicios.
Desarrollo de aplicaciones para Windows
Aplicaciones empresariales, integración de dispositivos y herramientas de comunicación, de los requisitos al desarrollo.
Reutilización y migración de activos existentes
Reutilización y migración de activos COM / ActiveX / OCX y dependencias de 32 o 64 bits.
Preguntas frecuentes
Preguntas habituales en las consultas sobre el tema del artículo.
- ¿Funciona ActiveX en WebView2?
- No funciona. El modo IE ejecuta dentro de Edge un IE11 real (motor Trident), por lo que ActiveX funciona tal cual, pero WebView2 está basado en Chromium y no tiene ningún mecanismo para alojar ActiveX. Por lo tanto, no es posible «simplemente trasladar» las pantallas dependientes de ActiveX a WebView2: hay que rediseñar el sistema trasladando al lado nativo (la aplicación host) las funciones que ActiveX cubría —comunicación serie, acceso a archivos, control de equipos dedicados, etc.— e invocarlas a través de mensajes Web. Este rediseño es, en la práctica, el esfuerzo real que supone adoptar WebView2.
- ¿Debo elegir Evergreen o Fixed Version para el runtime de WebView2?
- Por regla general, Evergreen (el runtime compartido que se actualiza automáticamente), ya que Microsoft lo recomienda explícitamente porque los parches de seguridad se aplican solos y el consumo de disco es menor. Windows 11 lo incluye de serie, pero como existen equipos sin él instalado, hay que incorporar en el instalador una comprobación de presencia y un bootstrap. Fixed Version (incluido con la aplicación) supera los 250 MB en los binarios que se distribuyen y traslada a usted la responsabilidad de distribuir con sus propias versiones las correcciones de vulnerabilidades del motor del navegador, por lo que solo debería elegirse en escenarios limitados, como equipos de fabricación sin conexión o entornos con una gestión de cambios muy estricta.
- ¿Por qué una aplicación WebView2 no arranca después de instalarla?
- El problema típico con el que se tropieza primero es la carpeta de datos de usuario (UDF, user data folder). WebView2 guarda ahí las cookies, la caché y los permisos, pero si no se indica su ubicación, por defecto intenta crearla junto al ejecutable; en una aplicación instalada bajo Program Files, esa escritura falla y se produce un error de inicialización. Es el fallo clásico que funciona en la máquina de desarrollo pero deja de funcionar en cuanto se instala. La solución es indicar siempre de forma explícita, al crear CoreWebView2Environment, una carpeta propia de la aplicación bajo %LOCALAPPDATA%. Colocarla en una unidad de red también hay que evitarlo, porque provoca lentitud y corrupción.
- ¿Cómo se comunican el código nativo y la página Web en WebView2?
- La base es una comunicación débilmente acoplada mediante mensajes Web. Desde el lado nativo se envía JSON con PostWebMessageAsJson, y el lado Web lo recibe con el evento message de window.chrome.webview. En sentido inverso se usan postMessage y el evento WebMessageReceived. En el lado receptor es importante verificar el origen del mensaje con e.Source y comprobar el type del mensaje contra una lista blanca. También existe la posibilidad de exponer directamente objetos .NET/COM con AddHostObjectToScript, pero como el impacto es grande si la página se ve comprometida, conviene limitarlo a contenido gestionado por la propia empresa y reducir al mínimo los métodos expuestos.
Perfil del autor
Página de presentación del autor del artículo.
Go Komura
Representante de KomuraSoft LLC
Especializado en desarrollo de software para Windows, consultoría técnica e investigación de fallos, sobre todo en proyectos con sistemas existentes y errores difíciles de reproducir.