ActiveX / OCX: cómo tratarlos hoy — tabla de decisión para mantener, envolver o reemplazar

· Actualizado el: · · COM, ActiveX, OCX, .NET, Desarrollo Windows, Modernización

Cuando aparece la palabra ActiveX / OCX en un proyecto, el ambiente suele ponerse un poco pesado.

  • Una aplicación VB6 o C++ / MFC antigua sigue en producción
  • El SDK de un equipo industrial o de medición solo se distribuye como OCX
  • La web interna depende de ActiveX y no logra salir del modo IE
  • Se quiere pasar de 32 bits a 64 bits, pero un solo OCX se niega

Sin embargo, aquí tanto «es viejo, así que se tira todo» como «funciona, así que se conserva para siempre» son posturas descuidadas. Lo importante es distinguir si ese ActiveX / OCX es un simple componente de interfaz o una superficie límite que carga con especificaciones de negocio o de equipos.

En este artículo se ordena, en el orden más fácil de decidir, cuál elegir entre mantener, envolver o reemplazar al encontrar un ActiveX / OCX.

El público objetivo son, por ejemplo, casos como estos.

  • Aplicaciones de escritorio existentes de la familia VB6 / MFC / WinForms
  • Migración por etapas hacia C# / .NET
  • Pantallas heredadas que incluyen WebBrowser / modo IE
  • Aplicaciones Windows que incluyen controles ActiveX de proveedores

Índice

  1. Conclusión primero (en una frase)
  2. Qué se entiende por ActiveX / OCX en este artículo
  3. La tabla de decisión que hay que mirar primero
    • 3.1. Panorama general
    • 3.2. Decisión de mantener
    • 3.3. Decisión de envolver
    • 3.4. Decisión de reemplazar
    • 3.5. La dependencia del navegador se piensa aparte
  4. Puntos que suelen desviar la decisión
    • 4.1. ¿Componente de interfaz o componente que carga con especificaciones?
    • 4.2. 32 bits / 64 bits y límites de proceso
    • 4.3. Registro, distribución, permisos y licencias
    • 4.4. STA / bucle de mensajes / callbacks
    • 4.5. ¿Hay pruebas? ¿Se puede observar?
  5. Recomendaciones por patrón típico
    • 5.1. Una aplicación de escritorio interna que funciona de forma estable
    • 5.2. Llevar un OCX de 32 bits al lado de 64 bits
    • 5.3. Pantallas basadas en IE / WebBrowser
    • 5.4. ActiveX con control de equipos o especificaciones propias
  6. Antipatrones habituales
  7. Lista de verificación al iniciar la migración
  8. Guía rápida de uso
  9. Resumen
  10. Este tipo de consulta encaja bien
  11. Referencias

1. Conclusión primero (en una frase)

  • Al ver un ActiveX / OCX, lo primero que hay que decidir no es «si es antiguo», sino qué es lo que ese componente asume
  • Si es un simple componente de interfaz, el reemplazo es relativamente sencillo
  • Si carga con control de equipos, informes, un formato de archivo propio o años de hábitos de operación, es más seguro envolverlo primero en lugar de reimplementarlo de golpe
  • Si funciona de forma estable en escritorio y el alcance del cambio es pequeño, mantenerlo también es una decisión perfectamente razonable
  • La dependencia de ActiveX en el navegador puede prolongarse, pero su futuro es limitado, así que conviene priorizar el reemplazo
  • No se puede cargar directamente un OCX de 32 bits en un proceso de 64 bits. Esto no se supera con voluntad
  • El registro, las DLL dependientes, los permisos de administrador, las licencias, STA / MTA y otras fricciones ajenas a la implementación suelen ser los puntos difíciles
  • Tanto «reescribirlo todo por si acaso» como «congelarlo para siempre por miedo» tienen una alta tasa de incidentes

En resumen, el orden de decisión es este.

  1. Qué tiene realmente ese OCX
  2. Si es necesario usarlo en el mismo proceso
  3. Si se atasca en 32 bits / 64 bits, registro o dependencia del navegador
  4. Si conviene crear un límite comprobable antes de reemplazar

Visto en este orden, resulta bastante más fácil de ordenar.

2. Qué se entiende por ActiveX / OCX en este artículo

Primero conviene fijar cómo se usan los términos en este artículo.

Término Significado en este artículo
COM El modelo de componentes binarios compatibles de Windows. Es la base de las interfaces públicas, el registro y el modelo de apartamento (Apartment Model)
ActiveX / OCX En la práctica se suele usar para referirse en conjunto a los controles basados en COM y a sus activos asociados. Con frecuencia incluye tanto los controles de interfaz .ocx como los componentes incrustados en IE o en un contenedor
Dependencia de WebBrowser / familia IE Aunque no sea ActiveX en sí, incluye navegadores incrustados o integraciones que dan por sentada «la visión del mundo de IE». En términos de decisión, es un problema bastante cercano

En sentido estricto, ActiveX y COM no son lo mismo. Sin embargo, los puntos donde surgen problemas en la práctica son bastante parecidos.

  • Si 32 bits y 64 bits encajan
  • Cómo distribuir el registro y las DLL dependientes
  • En qué host / contenedor funciona
  • Si se atasca en STA, el bucle de mensajes o los callbacks
  • Si queda alguna dependencia del navegador

Este artículo trata en conjunto estos puntos de decisión propios de la práctica.

Además, conviene reunir de antemano las siglas que aparecerán de aquí en adelante como si fueran obvias. Si en la lista de verificación del capítulo 7 se dice «identificar el ProgID y el CLSID» y eso no se entiende, no se puede avanzar.

Término Lectura / nombre completo Significado
CLSID Class ID GUID que identifica de forma única la implementación (clase) de un componente COM. Este valor es la clave del registro
ProgID Programmatic Identifier Nombre legible para humanos asignado al CLSID. Es una cadena como Excel.Application
IID Interface ID GUID que identifica de forma única una interfaz COM. Es distinto del CLSID
TLB Type Library Archivo binario que contiene información de tipos: interfaces, métodos y tipos de argumentos. Gracias a esto se puede invocar «con tipos» desde VB6 o .NET
RegAsm Assembly Registration Tool Herramienta incluida en .NET Framework. Registra un ensamblado .NET en el registro para que pueda usarse desde COM
AxHost Clase base para hospedar controles ActiveX en Windows Forms
AxImp ActiveX Control Importer Herramienta que genera un ensamblado wrapper para Windows Forms a partir de un OCX
in-proc / out-of-proc En proceso / fuera de proceso Si se ejecuta en el mismo proceso que quien lo invoca (DLL u OCX) o en un proceso separado (un servidor EXE)
LocalServer Forma en que un servidor COM se ejecuta como EXE en un proceso separado. Permite superar la barrera de bitness o aislar fallos
Reg-Free COM / side-by-side COM sin registro Mecanismo que resuelve COM con la información escrita en el manifiesto de la aplicación, sin necesidad de registro en el registro de Windows
Licencia de design-time / runtime En desarrollo / en ejecución En controles de proveedores, a veces el tratamiento de la licencia difiere entre colocarlo en pantalla en la máquina de desarrollo y ejecutarlo en el destino de distribución
adapter / facade Patrones de diseño que sustituyen una API antigua y detallada por una API más gruesa y conveniente para el equipo
STA / MTA Single / Multi Threaded Apartment Modelo de hilos de COM. Define desde qué hilo está permitido invocar

3. La tabla de decisión que hay que mirar primero

3.1. Panorama general

Empezar por esta tabla ya deja definida, en general, la línea a seguir.

Situación Primera elección Motivo
Depende de ActiveX en el navegador Tiende a reemplazar Edge en sí no admite ActiveX, y el modo IE se plantea como medida de prolongación de vida
El OCX funciona de forma estable en una aplicación de escritorio y el alcance del cambio es pequeño Tiende a mantener El costo de desmontarlo ahora suele ser mayor
Se quiere modernizar solo el entorno a .NET, pero el comportamiento del control es impredecible Tiende a envolver Es más seguro ordenar primero el límite
Se quiere llevar tal cual un OCX de 32 bits a un proceso de 64 bits Envolver / cambiar la configuración Es un límite que no se puede superar en modo in-proc
Solo se usa como componente de interfaz y hay alternativa disponible Tiende a reemplazar Suele bastar con un reemplazo superficial
Cada vez fallan por fin de soporte del proveedor, firma, registro o DLL dependientes Tiende a reemplazar El costo operativo se manifiesta como deuda técnica
Incorpora control de equipos, informes o un protocolo propio Tiende a envolver Primero hay que fijar el comportamiento, si no, no se puede estimar el costo del reemplazo
Árbol de decisión para mantener, envolver o reemplazar un ActiveX / OCXDiagrama de flujo que, partiendo de un ActiveX / OCX detectado, pregunta primero si depende del navegador, luego si es principalmente un componente de interfaz con alternativa disponible, después si incorpora control de equipos o especificaciones propias, y por último si el registro, la bitness o la distribución son un problema, para concluir en priorizar el reemplazo, envolver primero, revisar la configuración o mantenerlo.NoNoNoNoNoHay un ActiveX / OCX¿Depende del navegador?Priorizar el reemplazoEl modo IE es una medida de prolongación¿Es principalmente un componente de interfaz?¿Hay una alternativa equivalente?Estudiar el reemplazoEnvolver primero y ordenar el límite¿Incorpora control de equipos, especificación propia o lógica de informes?Envolver primeroPreparar pruebas y luego reemplazar por etapas¿El registro, la bitness o la distribución duelen?Revisar la configuraciónEstudiar out-of-proc / puente a proceso separado / Reg-Free COMMantener también es una decisión realista

A continuación se revisa cada patrón por orden.

3.2. Decisión de mantener

Que algo sea ActiveX / OCX no lo convierte de inmediato en objetivo de reemplazo. Si se reúnen estas condiciones, es habitual que mantenerlo sea lo más barato.

  • El alcance de uso está cerrado, y el entorno de operación (distribución interna, adjunto a un equipo, etc.) está fijado
  • El control funciona de forma estable en la actualidad y las demandas de cambio no son grandes
  • El proveedor sigue activo, o la propia empresa puede darle un mantenimiento mínimo
  • No depende del navegador y se completa sobre un host de escritorio existente
  • No hace falta cambiar por ahora el supuesto de 32 bits / 64 bits

Aquí lo importante es que mantener no equivale a abandonar. Si se decide mantener, conviene hacer al menos esto.

  • Dejar por escrito el SO compatible, la bitness, las DLL dependientes necesarias y el procedimiento de registro
  • Trasladar la instalación, el registro y su desinstalación a un script o instalador, en vez de a notas manuales
  • Preparar una prueba de humo en un entorno limpio
  • Concentrar en un solo lugar las llamadas al control, en vez de esparcirlas por toda la aplicación

Lo peor es seguir diez años con «funciona, así que no se toca» hasta que nadie pueda explicar los supuestos. Cuanto más se opte por mantener, más importante se vuelve visibilizar los supuestos.

3.3. Decisión de envolver

En la práctica, esta es la elección que da más trabajo.

Aquí «envolver» significa encerrar el ActiveX / OCX dentro de un límite estrecho y mostrarlo hacia el entorno como una nueva API o un nuevo componente de pantalla.

Esto resulta bastante eficaz. La razón es que, si se entra en una reimplementación total mientras aún no se ha terminado de entender el comportamiento del componente antiguo, se cae fácilmente en el doble sufrimiento de descubrir la especificación y reproducir los defectos a la vez. Es más seguro primero aislar el componente antiguo y solo ordenar el límite.

Existen varios patrones de envoltura.

Forma de envolver Situación en la que encaja Puntos a revisar
Host de WinForms + AxHost / Aximp Se quiere incrustar en una pantalla de escritorio existente, se quieren conservar solo unas pocas pantallas STA, eventos, dependencia de diseño (design-time), licencia
EXE auxiliar de 32 bits / COM LocalServer / puente en proceso separado Se quiere migrar al lado de 64 bits, se quiere aislar fallos Comunicación entre procesos, orden de arranque, monitorización, despliegue
Ventanilla de compatibilidad COM en el lado de .NET Se quieren conservar los llamadores COM existentes mientras se actualiza el contenido IID / CLSID / TLB / método de registro / bitness

Una vez decidida la estrategia, conviene anotar también cuál es el primer paso.

Forma de envolver Qué hacer primero Procedimiento detallado
Host de WinForms + AxHost En Visual Studio, clic derecho en el cuadro de herramientas → «Elegir elementos del cuadro de herramientas» → pestaña «Componentes COM» y seleccionar el control. Desde línea de comandos, aximp COM/OCX/ActiveX: la trampa del registro y la bitness en el desarrollo con Visual Studio
EXE auxiliar de 32 bits / LocalServer Registrar el EXE de 32 bits como servidor COM y llamarlo out-of-proc desde el lado de 64 bits Caso práctico de COM: cuando se quiere llamar a una DLL de 64 bits desde una aplicación de 32 bits
Reg-Free COM Escribir file y comClass en el manifiesto de la aplicación y resolverlo sin registro en el registro de Windows Qué es Reg-Free COM: el mecanismo para usar COM sin registro
Ventanilla de compatibilidad COM en el lado de .NET Exponer el lado de .NET como COM y, si hace falta, generar el TLB con dscom Cómo usar una DLL de .NET 8 con tipos desde VBA: exposición COM y TLB con dscom

aximp se ejecuta desde el Developer Command Prompt de Visual Studio.

aximp C:\path\to\MyControl.ocx

Con esto se generan dos archivos: el runtime callable wrapper de tipo COM y el wrapper para Windows Forms derivado de AxHost. El nombre de archivo no proviene del nombre de archivo original, sino que se determina a partir del ProgID, así que conviene prestar atención a ese punto. En el ejemplo de la documentación de Microsoft, a partir de msdxm.ocx se obtienen MediaPlayer.dll y AxMediaPlayer.dll. Se agrega este último como referencia y se coloca AxMediaPlayer en el formulario.

En el caso de Reg-Free COM, el manifiesto mínimo del lado de la aplicación tiene esta forma.

<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32" name="MyApp" version="1.0.0.0" />
  <file name="MyControl.ocx">
    <comClass
      clsid="{01234567-89AB-CDEF-0123-456789ABCDEF}"
      threadingModel="Apartment"
      progid="MyCompany.MyControl.1" />
  </file>
</assembly>

Con el esquema LocalServer, en el registro la ruta del EXE se guarda en HKEY_CLASSES_ROOT\CLSID\{CLSID}\LocalServer32. En un servidor EXE creado con ATL o MFC, por convención suele estar preparado para autorregistrarse y desregistrarse con MyServer.exe /regserver y /unregserver. Sin embargo, la vista del registro se divide según la bitness, así que hay que tener siempre presente que el EXE de 32 bits se registra en el registro del lado de 32 bits.

Lo especialmente importante es no copiar tal cual, al envolver, 200 métodos de la API antigua. Hacer eso solo importa los condicionamientos antiguos al código nuevo sin cambiar nada.

Al envolver, tener presentes estos puntos ayuda bastante.

  • Usar métodos de grano grueso
  • No dejar que el código de pantalla toque el OCX directamente
  • Recoger en el límite los registros necesarios en caso de fallo
  • Decidir en el límite las responsabilidades de tiempo de espera, reintento y conversión de excepciones
  • Dejarlo de forma que el futuro reemplazo también pueda hacerse con la misma interfaz

A veces también se quiere conservar solo la entrada COM en el lado de .NET nuevo. En ese caso es realista una configuración de «actualizar el contenido, pero mantener solo el contrato COM». Sin embargo, no siempre basta con «usar RegAsm por ahora» con la mentalidad de la época de .NET Framework. Conviene diseñar de antemano el tratamiento del host COM, el TLB, la bitness y Registry-Free COM del .NET actual, porque después resulta más cómodo. Este punto está explicado con el procedimiento detallado en Cómo usar una DLL de .NET 8 con tipos desde VBA: exposición COM y TLB con dscom y en Qué es Reg-Free COM: el mecanismo para usar COM sin registro.

3.4. Decisión de reemplazar

El reemplazo encaja principalmente en los casos donde el problema es la antigüedad superficial.

En estos casos conviene priorizar el reemplazo.

  • El ActiveX solo se usa como componente de interfaz
  • El proveedor ya ofrece un sucesor para .NET / WPF / WebView2
  • La dependencia del navegador o el supuesto de IE está frenando el avance
  • Se falla siempre en el registro, la firma, los permisos de administrador o la configuración de seguridad
  • Existen pruebas o escenarios de negocio con los que se puede validar una implementación alternativa

Por el contrario, si solo por parecer anticuado se intenta descartar de golpe un componente que también carga con control de equipos o lógica de informes, el resultado suele ser un pantano.

Si se va a reemplazar, conviene empezar por la interfaz.

  • Cuadrículas (grids)
  • Calendarios
  • Árboles (trees)
  • Zonas de visualización de navegador
  • Ayudas de entrada sencillas

Estos elementos son relativamente fáciles de reemplazar. Por otro lado, hay casos que parecen interfaz pero tienen un contenido denso por dentro.

  • ActiveX de control de equipos de proveedores
  • Controles integrados con la impresión o la generación de informes
  • Controles que incorporan la lectura y escritura de un formato de archivo propio
  • Controles que asumen callbacks de COM o supuestos de hilos

Si se confunde esta diferencia, la estimación de esfuerzo se desmorona de golpe.

3.5. La dependencia del navegador se piensa aparte

Aquí conviene tratarlo como un caso bastante distinto.

El ActiveX en el navegador, a diferencia del OCX de escritorio, tiene una razón bastante débil para seguir extendiéndose en el futuro.

El motivo es simple: los cimientos de los navegadores actuales ya no tienen ese terreno como campo de batalla principal. Microsoft Edge en sí no admite ActiveX. Por otro lado, el modo IE puede usarse, para los sitios configurados, como una capa de compatibilidad que emplea el motor de la familia IE y ejecuta algunas funciones de IE, incluido ActiveX.

En otras palabras,

  • Se puede prolongar la vida para que funcione ahora
  • Pero, como diseño a largo plazo, no tiene un futuro amplio

Esto es lo que ocurre.

Lo mismo sucede con el control WebBrowser incrustado en aplicaciones Windows. WebBrowser arrastra la visión del mundo de la familia IE, así que si lo único que se necesita es mostrar HTML, resulta más natural que cualquier trabajo nuevo desde ahora tenga a WebView2 como primera opción.

Sin embargo, aquí hay que tener cuidado: WebView2 no es un componente de sustitución completo de WebBrowser.

  • Scripts que dan por sentado el DOM de IE
  • Dependencia de ActiveX
  • Supuestos alrededor de window.external
  • Comportamiento que da por sentadas las zonas de seguridad o la intranet

Estos elementos no se trasladan tal cual. Si se va a reemplazar, hay que rediseñar no solo el motor de renderizado, sino también la superficie de conexión entre el navegador y el código nativo.

4. Puntos que suelen desviar la decisión

4.1. ¿Componente de interfaz o componente que carga con especificaciones?

Esto es lo más importante.

Con una cuadrícula o un calendario antiguos, basta con revisar la compatibilidad de la apariencia y de los eventos para que el asunto avance bastante. Por otro lado, un ActiveX que carga con control de equipos, informes o un formato propio tiene, detrás de la apariencia, un bloque de especificaciones.

Aunque parezcan igualmente «un control en pantalla», en realidad hay un abanico así de amplio.

  • Un simple componente de visualización en lista
  • Un componente que envía órdenes a un equipo mediante un protocolo propio
  • Un componente que internamente maneja tiempos de espera, reconexión, reenvío y absorción de excepciones
  • Un componente que carga con la compatibilidad de formatos de impresión o exportación

Reimplementar de golpe lo segundo suele convertirse en un proyecto de descubrimiento de especificaciones. Aquí es más seguro envolver primero.

4.2. 32bit / 64bit y límites de proceso

Este punto se pasa por alto con frecuencia, pero es bastante esencial.

Un OCX en modo in-proc debe coincidir en bitness con el proceso que lo carga. Es decir, no se puede cargar tal cual un OCX de 32 bits en una aplicación de 64 bits.

En este punto, las opciones realistas suelen reducirse a estas tres.

  • Mantener por ahora también el lado de la aplicación host en 32 bits
  • Encerrarlo en un proceso separado de 32 bits y conectarlo con el lado de 64 bits mediante IPC o COM out-of-proc
  • Reemplazar primero las partes donde se pueda eliminar esa dependencia del OCX

Aquí, la idea de «como es Any CPU, algo se podrá hacer» normalmente no funciona. Incluso al crear una ventanilla de compatibilidad COM en el lado de .NET nuevo, la apariencia del código managed y la bitness real del host COM son cuestiones distintas. Si se empieza este punto de forma descuidada, aparece el molesto caso de que la compilación funciona pero en el destino de distribución no se ejecuta.

4.3. Registro, distribución, permisos y licencias

Técnicamente se puede invocar, pero muere en la distribución. Esto es bastante habitual con ActiveX / OCX.

Los puntos difíciles suelen ser estos.

  • El supuesto de regsvr32 depende de una persona
  • La colocación de las DLL dependientes es implícita
  • Se necesitan permisos de administrador, pero eso no quedó reflejado en el procedimiento de operación
  • La licencia de design-time y de runtime del control del proveedor está separada
  • Funciona en la máquina de desarrollo, pero no en un entorno limpio

Estos puntos pueden detener el proyecto sin tocar ni una línea de código.

Existen casos en los que una configuración sin registro o una colocación side-by-side facilita las cosas, pero no son polvo mágico. Hace falta confirmar la compatibilidad con el contenedor y con el método de distribución.

En resumen, la migración de ActiveX / OCX no es solo implementación, también es diseño de distribución. Si se posterga este punto, al final se tropieza de forma aparatosa.

4.4. STA / bucle de mensajes / callbacks

ActiveX / OCX no es una simple llamada a una DLL. A veces tiene los supuestos del modelo de hilos de COM y del bucle de mensajes.

Conviene prestar especial atención a casos como estos.

  • Solo es estable con el supuesto del hilo de interfaz
  • Se asume STA, pero se llama con descuido desde el lado MTA
  • Un callback vuelve mientras una llamada síncrona está en curso
  • El supuesto de en qué hilo se reciben los eventos es ambiguo

Al principio, este tipo de cosas se presenta con la cara de una historia de fantasmas: «a veces se cuelga», «a veces no llega el evento». Pero en el fondo, normalmente se trata de una violación de un supuesto.

Por eso, tanto al envolver como al reemplazar, conviene fijar de antemano en qué hilo se crea, desde qué hilo se llama y dónde se reciben los eventos.

4.5. ¿Hay pruebas? ¿Se puede observar?

El reemplazo es difícil no solo porque el código sea antiguo. Es porque no existe una forma de afirmar que «funcionó igual».

Con solo tener esto, la diferencia ya es considerable.

  • Pruebas de humo por escenario de operación
  • Muestras de entrada y salida
  • Capturas de pantalla o muestras de informes
  • Patrones de error y comportamiento esperado
  • Registros en caso de tiempo de espera agotado o equipo no conectado

Especialmente cuando hay equipos o informes de por medio, ocurre la rareza de que el comportamiento real pesa más que la documentación de especificaciones. Si aquí no hay medios de observación, el reemplazo se convierte en una excavación arqueológica.

5. Recomendaciones por patrón típico

5.1. Una aplicación de escritorio interna que funciona de forma estable

La recomendación es tender a mantener.

Con estas condiciones, suele ser mejor no desmontarlo a la fuerza.

  • Se usa solo internamente
  • Los terminales o el sistema operativo objetivo están razonablemente fijados
  • Ese OCX solo se usa en unas pocas pantallas
  • Las demandas de modificación son pequeñas y la vida útil se puede prever

Sin embargo, en lugar de dejarlo tal cual desnudo, concentrar solo los puntos de llamada resulta útil más adelante.

Es decir, la estrategia queda así.

  • Por ahora, se mantiene
  • Pero solo se ordena el límite
  • Cuando haga falta reemplazar, ya se puede empezar desde ese punto

Esta estructura en tres pasos es la más sencilla.

5.2. Llevar un OCX de 32 bits al lado de 64 bits

La recomendación es envolver / cambiar la configuración.

Aquí, ir de frente lleva a un punto muerto. Porque no se puede meter un OCX de 32 bits en modo in-proc dentro de un proceso de 64 bits.

En la práctica, resulta más manejable encerrarlo en un proceso auxiliar de 32 bits o en un LocalServer, y comunicarse con la aplicación de 64 bits mediante una API de grano grueso.

Puente entre una aplicación de 64 bits y un OCX de 32 bitsDiagrama de secuencia que muestra a la aplicación .NET de 64 bits pidiendo con una API de grano grueso al auxiliar de 32 bits o LocalServer, este realizando una llamada in-proc al OCX de 32 bits, el OCX devolviendo un resultado o evento al auxiliar, y el auxiliar devolviendo el resultado ya convertido a la aplicación.OCX de 32 bitsAuxiliar de 32 bits / LocalServerAplicación .NET de 64 bitsOCX de 32 bitsAuxiliar de 32 bits / LocalServerAplicación .NET de 64 bitsSolicitud con una API de grano gruesoLlamada in-procResultado / eventoResultado ya convertido

El punto clave aquí es no retransmitir tal cual todos los métodos detallados. El límite entre procesos se vuelve pesado enseguida si se hace pasar por él un gran volumen de llamadas pequeñas.

  • Aproximarse a un grano de una operación = una solicitud
  • Dar forma a los valores de retorno y errores en unidades con sentido
  • Recoger los registros en el límite

Con esta forma, más adelante también resulta más cómodo el momento de reemplazar de verdad el contenido.

5.3. Pantallas basadas en IE / WebBrowser

La recomendación es priorizar el reemplazo.

Aquí es un territorio donde «funciona ahora» y «se puede mantener cómodamente en el futuro» no suelen coincidir. El modo IE ayuda bastante en cuanto a compatibilidad, pero aun así el supuesto sigue siendo el de la familia IE.

Por eso conviene separar el razonamiento así.

  • Usar el modo IE para prolongar la vida y no detener la operación interna
  • Pero no confundir la prolongación con un diseño permanente
  • Elegir el destino del reemplazo entre WebView2, la web pura o un híbrido de interfaz nativa + web

También conviene escribir el tratamiento concreto del lado de la prolongación de vida. El modo IE no es algo que «funciona solo con instalar Edge»: solo se abre con el motor de la familia IE cuando el sitio de destino se especifica mediante una directiva (policy). Hay tres puntos de entrada para la configuración.

Método Configuración Nota
Enumerar sitios En la directiva de grupo «Configure the Enterprise Mode Site List» de Microsoft Edge 78 o posterior, especificar la ubicación del XML de la lista de sitios en modo empresarial Es la forma más básica
Reutilizar la lista del lado de IE antiguo Directiva «Use the Enterprise Mode IE website list» de Internet Explorer Si existe la directiva del lado de Edge, esta tiene prioridad
Aplicarlo a toda la intranet Habilitar la directiva de grupo «Send all intranet sites to Internet Explorer» de Microsoft Edge 77 o posterior El alcance se amplía, así que no sustituye a un inventario

Como requisito previo, hace falta que Windows y Edge tengan las actualizaciones más recientes instaladas, que la plantilla administrativa de Microsoft Edge esté implementada y que la función de Windows para Internet Explorer 11 esté habilitada. Si falta alguno de estos requisitos, el modo IE falla.

Además, en el modo IE funcionan los controles ActiveX y los Browser Helper Object. Es decir, la prolongación de vida realmente funciona. Precisamente por eso, si se sigue usando sin fijar una condición de finalización, ya no se puede salir de ahí. El tema de cómo desmontarlo está reunido en Guía para salir de un sistema dependiente del modo IE.

En particular, si el control WebBrowser se usa solo como visor de HTML, la prioridad de reemplazo es alta.

Por otro lado, si el ActiveX dentro del navegador tiene además un rol como el de archivos locales, equipos, firmas o complementos propios, eso ya no es un cambio de motor de renderizado, sino un rediseño de la integración nativa. Aquí el tema se pone algo más pesado.

5.4. ActiveX con control de equipos o especificaciones propias

La recomendación es envolver primero.

Este tipo tiene un contenido más denso de lo que aparenta. Aunque la documentación del SDK sea escasa, como resultado de años de funcionamiento en el terreno, a veces se han ido acumulando de forma implícita comportamientos como estos.

  • Cómo esperar cuando falla la conexión
  • Reintentos tras un tiempo de espera agotado
  • Orden de los eventos
  • Procesamientos de contorno que absorben las peculiaridades del equipo real
  • Interpretación de excepciones o códigos de error

Si este tipo de componente se rehace bajo la lógica de «total, es viejo», con bastante probabilidad las pruebas en campo se incendian.

Por eso, es más seguro empezar desde aquí.

  1. Encerrar el componente existente dentro del límite
  2. Añadir registros para que se pueda ver qué está pasando
  3. Reunir escenarios de prueba y patrones del equipo real
  4. Después, extraer el rango que se puede reemplazar

No tiene nada de vistoso, pero en la práctica es lo que más resultado da.

6. Antipatrones habituales

Antipatrón Qué lo hace difícil Primera corrección
Reescribir todo porque hay ActiveX Es fácil que surjan omisiones de especificación y una explosión de esfuerzo Primero, inventario y extracción de límites
Intentar meter tal cual un OCX de 32 bits en una aplicación de 64 bits Es imposible por principio Aislarlo en el lado de 32 bits o cambiar la configuración
Llamar directamente a la API del control desde toda la pantalla Es fácil que se vuelva imposible de reemplazar Aproximarse a un adapter / facade
Operar el procedimiento de regsvr32 de forma manual Cada vez falla por diferencias de entorno Estudiar el instalador, el script o el uso de manifiesto
Confiarse porque existe el modo IE Es fácil confundir la prolongación con el tratamiento permanente Fijar el plan de reemplazo y la condición de finalización
No registrar el comportamiento antes de reemplazar No se puede determinar cuándo está terminado Preparar pruebas de humo, datos de muestra y registros

De estos, hay tres que se ven especialmente a menudo en la práctica.

  1. Apresurar una reescritura total
  2. Tomar a la ligera la barrera de bitness
  3. Esparcir la API por toda la aplicación

Con solo evitar estos tres, la tasa de incidentes baja considerablemente.

7. Lista de verificación al iniciar la migración

En un proyecto de ActiveX / OCX, suele salir mejor hacer primero un inventario en vez de entrar directamente a implementar. El orden suele ser este.

  1. Identificar los OCX / DLL en uso
    • Nombre de archivo, versión, ProgID, CLSID, proveedor, si tienen licencia
  2. Identificar dónde se usan
    • Pantallas, funciones, informes, equipos, procesos por lotes, integración con Office, etc.
  3. Confirmar la bitness y las condiciones del host
    • 32 bits / 64 bits, in-proc / out-of-proc, supuesto de STA, dependencia del navegador
  4. Confirmar las condiciones de distribución
    • Método de registro, DLL dependientes, permisos de administrador, instalación silenciosa, reproducibilidad en entorno limpio
  5. Crear pruebas de humo
    • Incluir no solo el caso normal, sino también fallos, equipo no conectado y tiempo de espera agotado
  6. Crear el límite
    • Adapter, service, facade, puente a proceso separado, etc.
  7. Probar con una unidad pequeña: una pantalla, una función, un equipo
  8. Desde el límite que funcionó bien, ampliar por orden mantener / envolver / reemplazar

Si se salta este procedimiento, después resulta difícil explicar siquiera qué fue lo difícil.

8. Guía rápida de uso

Situación Qué elegir primero
Estable y de uso interno, con cambios pequeños Mantener
Se quiere modernizar solo el entorno a .NET Envolver
Choca 32 bits con 64 bits Envolver / cambiar la configuración
Dependencia de IE / WebBrowser / ActiveX en el navegador Reemplazar
Es un simple componente de interfaz con alternativa disponible Reemplazar
Carga con control de equipos, informes o especificaciones propias Envolver
Falla siempre en el registro o la distribución Envolver o reemplazar

Si hay dudas, distinguir primero si se trata de un componente de interfaz o de una superficie límite que carga con especificaciones ayuda bastante a no equivocarse.

9. Resumen

Cómo tratar un ActiveX / OCX no es algo que se decida por «rechazarlo porque es legado».

Hay cuatro puntos que conviene revisar primero.

  1. Si ese componente es una simple interfaz o una superficie límite que carga con especificaciones
  2. Si es necesario usarlo en el mismo proceso
  3. Si se atasca en 32 bits / 64 bits, registro, dependencia del navegador o licencias
  4. Si se puede observar el comportamiento antes de reemplazar

Con estos cuatro puntos claros, en general se puede ordenar así.

  • Si funciona de forma estable y la vida útil se puede prever, mantener
  • Si solo se quiere modernizar el entorno, envolver
  • Si es un componente de interfaz o depende del navegador, reemplazar
  • Si es un componente que carga con un bloque de especificaciones, primero envolver y luego reemplazar por etapas

La tecnología legada no es un objeto de burla, sino algo material que concentra historia y contratos. Sin embargo, sí hace falta un diseño de límites para poder convivir con ese material.

Cuando se aprende a combinar mantener, envolver y reemplazar, un proyecto de ActiveX / OCX se convierte, de repente, en un problema manejable.

10. Este tipo de consulta encaja bien

Este tema suele generar valor incluso solo con ordenar la estrategia antes de entrar directamente al desarrollo.

Por ejemplo, este tipo de consultas encaja bastante bien.

  • Se quiere hacer un inventario para saber qué OCX conviene realmente reemplazar
  • Se quiere ordenar primero solo los puntos de atasco de 32 bits / 64 bits
  • Se quiere migrar hacia .NET, pero conservando solo la entrada COM
  • Se quiere comparar la medida de prolongación de vida frente a la retirada de un ActiveX cuyo proveedor cerró
  • Se quiere ver por dónde se puede empezar a desmontar la dependencia de IE / WebBrowser
  • Se quiere separar de forma segura, primero, solo una pantalla o una función

En un proyecto de ActiveX / OCX, la partida se suele decidir más por cómo se trazan los límites que por la implementación en sí. Empezar por el ordenamiento de la situación actual, la comparación de configuraciones y el diseño del orden de migración, como paso previo a una renovación total, ya aporta bastante valor.

11. Referencias

  • Microsoft Learn: AxHost Class (System.Windows.Forms)
    • https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.forms.axhost
  • Microsoft Learn: Aximp.exe (importador de controles ActiveX para Windows Forms)
    • https://learn.microsoft.com/ja-jp/dotnet/framework/tools/aximp-exe-windows-forms-activex-control-importer
  • Microsoft Learn: How to: Add ActiveX Controls to Windows Forms
    • https://learn.microsoft.com/en-us/dotnet/desktop/winforms/controls/how-to-add-activex-controls-to-windows-forms
  • Microsoft Learn: Expose .NET Core components to COM
    • https://learn.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com
  • Microsoft Learn: Registration-Free COM Interop
    • https://learn.microsoft.com/en-us/dotnet/framework/interop/registration-free-com-interop
  • Microsoft Learn: preguntas frecuentes sobre Microsoft Edge
    • https://learn.microsoft.com/ja-jp/deployedge/microsoft-edge-frequently-asked-questions
  • Microsoft Learn: What is Internet Explorer (IE) mode?
    • https://learn.microsoft.com/en-us/deployedge/edge-ie-mode
  • Microsoft Learn: WebBrowser Class (System.Windows.Forms)
    • https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.webbrowser
  • Microsoft Learn: Introduction to Microsoft Edge WebView2
    • https://learn.microsoft.com/en-us/microsoft-edge/webview2/
  • KomuraSoft Blog: Conceptos básicos de STA/MTA en COM para evitar cuelgues
    • https://comcomponent.com/es/blog/sta-mta-com-relationship/
  • KomuraSoft Blog: por qué conviene crear un wrapper con C++/CLI al usar una DLL nativa de C++ desde C#
    • https://comcomponent.com/es/blog/cpp-cli-wrapper-for-native-dlls/
  • KomuraSoft Blog: caso práctico de COM: cuando se quiere llamar a una DLL de 64 bits desde una aplicación de 32 bits
    • https://comcomponent.com/es/blog/com-case-study-32bit-to-64bit/
  • KomuraSoft Blog: qué es COM / ActiveX / OCX: diferencias y relaciones explicadas en conjunto
    • https://comcomponent.com/es/blog/what-is-com-activex-ocx/
  • KomuraSoft Blog: cómo usar una DLL de .NET 8 con tipos desde VBA: exposición COM y TLB con dscom
    • https://comcomponent.com/es/blog/dotnet8-dll-typed-vba-com-dscom-tlb/
  • KomuraSoft Blog: qué es Reg-Free COM: el mecanismo para usar COM sin registro
    • https://comcomponent.com/es/blog/what-is-reg-free-com/
  • KomuraSoft Blog: COM/OCX/ActiveX, la trampa del registro y la bitness en el desarrollo
    • https://comcomponent.com/es/blog/com-ocx-activex-pitfalls-visual-studio-bitness-admin-rights/
  • KomuraSoft Blog: guía para salir de un sistema dependiente del modo IE
    • https://comcomponent.com/es/blog/ie-mode-internal-web-system-life-extension-and-exit/
  • KomuraSoft Blog: ¿es WebView2 la respuesta después del modo IE? Restricciones de ActiveX y un diseño de migración realista
    • https://comcomponent.com/es/blog/webview2-embed-web-ui-in-windows-apps/

Artículos recientes con las mismas etiquetas para profundizar en temas cercanos.

Estas páginas sitúan el tema en un contexto más amplio de servicios y decisiones.

El artículo está directamente relacionado con los siguientes servicios.

Preguntas frecuentes

Preguntas habituales en las consultas sobre el tema del artículo.

¿Se debe reemplazar un ActiveX / OCX?
No se decide por «si es antiguo», sino por lo que ese componente asume realmente. Si es un simple componente de interfaz con alternativa disponible, se reemplaza; si carga con control de equipos, informes o un formato de archivo propio, primero conviene envolverlo para ordenar los límites; y si funciona de forma estable y el alcance del cambio es pequeño, mantenerlo también es una decisión razonable. Tanto «reescribirlo todo por si acaso» como «congelarlo para siempre por miedo» son opciones con una alta tasa de incidentes.
¿Se puede usar un OCX de 32 bits desde una aplicación de 64 bits?
No en modo in-proc. Un OCX debe coincidir en bitness con el proceso que lo carga, y esta es una restricción de principio. Las opciones realistas son tres: mantener por ahora también el proceso host en 32 bits, encerrarlo en un proceso separado de 32 bits (un EXE auxiliar o un COM LocalServer) y comunicarlo con el lado de 64 bits mediante IPC o COM out-of-proc, o reemplazar primero las partes donde se pueda eliminar esa dependencia del OCX.
¿Qué se debe hacer con la dependencia de ActiveX en el navegador?
Conviene priorizar el reemplazo. Microsoft Edge en sí no admite ActiveX, y el modo IE se plantea como una medida de prolongación de vida. El control WebBrowser arrastra igualmente la visión del mundo de IE, así que si lo único que se necesita es mostrar HTML, WebView2 es la primera opción. Sin embargo, WebView2 no es un componente de sustitución completo: los scripts que dan por sentado el DOM de IE y los supuestos alrededor de window.external no se trasladan tal cual.
¿Qué significa concretamente «envolver» un ActiveX / OCX?
Significa encerrar el ActiveX / OCX dentro de un límite estrecho y mostrarlo hacia el entorno como una nueva API o un nuevo componente de pantalla. Existen varios patrones: un host de WinForms con AxHost, un puente en proceso separado mediante un EXE auxiliar de 32 bits o un LocalServer, o una ventanilla de compatibilidad COM en el lado de .NET. Al envolver, en lugar de copiar en bloque la API antigua, conviene usar métodos de grano más grueso, decidir en el límite las responsabilidades de registro, tiempo de espera y conversión de excepciones, y dejar el diseño de forma que el futuro reemplazo pueda hacerse con la misma interfaz.

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.

Volver al blog