¿Qué es Reg-Free COM? - El mecanismo para usar COM sin registro

· Actualizado el: · · COM, Reg-Free COM, Registration-Free COM, Desarrollo en Windows, Tecnología heredada

En los proyectos de COM / ActiveX / OCX aparecen los mismos problemas cada vez que hay que distribuir o actualizar la aplicación.

  • Se necesita regsvr32
  • Suele requerir privilegios de administrador
  • Choca con otra versión que ya instaló otra aplicación
  • Al desinstalar, arrastra a otros productos
  • Funciona en la máquina de desarrollo, pero no en un entorno limpio

Reg-Free COM permite reducir bastante estas molestias. Sin embargo, a pesar de su nombre, no es «una magia que elimina por completo las molestias de COM». Lo que desaparece es, sobre todo, la carga que arrastra el registro global. No hace desaparecer las dificultades relacionadas con la bitness, las DLL dependientes, las bibliotecas de tipos ni el modelo de subprocesos.

En este artículo organizamos Reg-Free COM centrándonos en el contexto de usar COM DLL / OCX de forma local a la aplicación en aplicaciones de escritorio Windows.

Público objetivo y requisitos previos

Este artículo está dirigido a desarrolladores que distribuyen aplicaciones de escritorio Windows que usan COM DLL / OCX existentes y quieren dejar atrás regsvr32 y los privilegios de administrador. Se asume que ya ha tenido contacto al menos una vez con los fundamentos de COM (CLSID, ProgID, CoCreateInstance, servidor in-proc). Si todavía tiene dudas al respecto, es más rápido leer primero «¿Qué es COM / ActiveX / OCX? - Diferencias y relación explicadas».

La parte de procedimientos usa mt.exe y sxstrace del Windows SDK, así que se asume un entorno con Visual Studio o el Windows SDK instalado.

1. Primero, la conclusión en pocas palabras

Dicho de forma directa pero útil, es esto:

  • Reg-Free COM es una forma de mantener la información de registro de COM en un manifiesto en lugar de en el registro de Windows
  • En tiempo de ejecución, al resolver CoCreateInstance o CLSIDFromProgID, primero se consulta el contexto de activación
  • Por eso es posible mantener la COM DLL / OCX de forma privada por cada aplicación
  • Sus principales ventajas son facilitar la distribución por copia directa (XCOPY), evitar más fácilmente los conflictos de versión y reducir el riesgo de que una desinstalación quede rota
  • Sin embargo, el problema de 32 bits / 64 bits no desaparece. Esto no se puede evitar con la forma de escribir el manifiesto
  • Además, hay que seguir considerando por separado las DLL dependientes, las bibliotecas de tipos, las referencias en tiempo de diseño y las dependencias de registro no estándar
  • En la práctica, encaja bastante bien cuando se quiere aislar componentes COM propios de una aplicación

En resumen, Reg-Free COM es un mecanismo que devuelve la activación de COM al ámbito de cada aplicación.

2. Reg-Free COM en el sentido de este artículo

Reg-Free COM es la abreviatura de Registration-Free COM. En español a veces se lo llama «COM sin registro».

Aquí, «sin registro» significa que no se depende por completo del registro global de Windows (HKCR / CLSID / InprocServer32, etc.) para usar COM. No significa que desaparezca el propio COM, ni que deje de hacer falta el GUID.

Los objetos principales de este artículo son los siguientes:

  • COM DLL nativas
  • Servidores COM basados en ATL
  • ActiveX / OCX
  • Interoperabilidad COM basada en .NET Framework
  • Exposición mediante el COM host de .NET 5+ / .NET 8

Y, al contrario, hay dos puntos que quiero recalcar en este artículo:

  1. Reg-Free COM trata sobre la «activación»
  2. La distribución de información de tipos y la configuración de referencias en tiempo de diseño pueden quedar como cuestiones aparte

Mezclar estos dos puntos hace que la discusión se vuelva bastante confusa.

3. Un vistazo general primero

Antes de entrar en el diagrama, conviene definir de antemano los cuatro términos que aparecen una y otra vez en este artículo.

Término Significado
Contexto de activación (activation context) Es una estructura de datos en tiempo de ejecución que mantiene «qué versión de qué assembly está usando este hilo ahora mismo». CoCreateInstance la consulta antes que el registro
side-by-side assembly Es el mecanismo de Windows para que componentes con el mismo nombre pero distintas versiones coexistan en la misma máquina. Se identifica mediante un manifiesto, donde assemblyIdentity funciona como etiqueta de identificación
Manifiesto de la aplicación Es el XML asociado al EXE, donde se declara «de qué side-by-side assembly depende este programa»
Manifiesto del componente (assembly manifest) Es el XML asociado al componente, donde se declara «qué archivos incluye este assembly y qué clases COM expone». Aquí se traslada la información que antes residía en el registro

El contexto de activación se mantiene por hilo. COM traspasa el contexto de activación del hilo que crea el objeto al hilo del host antes de llamar a LoadLibrary o DllGetClassObject, así que el lado que hace la llamada no necesita preparar nada especial.

Dicho esto, es más rápido ver el panorama completo de un vistazo.

Flujo de resolución de Reg-Free COMDiagrama que muestra cómo MyApp.exe depende de su manifiesto de aplicación, que declara una dependentAssembly resuelta por el manifiesto del componente hacia el archivo, la clase COM y la biblioteca de tipos que apuntan a la DLL, y cómo en paralelo el contexto de activación de la aplicación es consultado por CLSIDFromProgID o CoCreateInstance para llegar a la misma DLLMyApp.exeApplication ManifestdependentAssemblyComponent / Assembly Manifestfile / comClass / typelibVendorControl.dll / .ocxActivation ContextCLSIDFromProgID / CoCreateInstance

En COM normal, al llamar a CoCreateInstance, se recorre el registro para decidir qué DLL cargar. En Reg-Free COM, antes de eso se consulta el contexto de activación actualmente vigente, y se resuelve a partir de la información del manifiesto escrita allí.

Por esto, en la misma máquina resulta más fácil que la aplicación A y la aplicación B trabajen cada una con una versión distinta del mismo componente COM. Es, en cierto modo, devolver un poco la cultura compartida de COM hacia un enfoque más local a la aplicación.

4. Por qué la distribución COM tradicional tiende a ser pesada

La distribución COM tradicional es pesada no tanto porque COM en sí sea malo, sino porque parte de la premisa del registro global.

Para usar una clase COM se necesita, a grandes rasgos, esta información:

Información Función
CLSID El GUID que identifica de forma única a la clase
ProgID Un nombre fácil de manejar para las personas
InprocServer32 Indica qué DLL cargar
ThreadingModel La premisa del modelo de subprocesos, como Apartment o Both
TypeLib La información de tipos

Cuando esta información entra en el registro, resulta conveniente para toda la máquina, porque es fácil compartirla entre varias aplicaciones.

Sin embargo, en la práctica, este mismo hecho de compartir se vuelve en contra.

  • El instalador de un producto sobrescribe el registro COM de otro producto
  • Un desinstalador «cree que solo está borrando lo suyo» y rompe un COM compartido
  • El registro que casualmente está presente en la máquina de desarrollo no existe en la máquina de producción
  • El registro de 32 bits y el de 64 bits no coinciden, y el síntoma se manifiesta de forma inquietante y desajustada

Es decir, con bastante frecuencia es el modelo de distribución, más que COM en sí, lo que da problemas a la gente. Reg-Free COM es un mecanismo para reducir esta dificultad del modelo de distribución.

5. El funcionamiento de Reg-Free COM

5.1 Declarar las dependencias en el manifiesto de la aplicación

Primero, el lado de la aplicación declara de qué side-by-side assembly depende en el manifiesto de la aplicación.

Este manifiesto se puede manejar de dos formas:

  • Colocarlo junto al EXE, con un nombre como MyApp.exe.manifest
  • Incrustarlo como recurso dentro del EXE

En la práctica, es habitual elegir el archivo externo cuando se quiere facilitar la distribución y el reemplazo, e ir a la incrustación cuando se prioriza la robustez y la simplicidad de la distribución.

Además, cuando existen tanto la versión de archivo externo como la incrustada, tiene prioridad el manifiesto presente en el sistema de archivos.

5.2 Registrar la información COM en el manifiesto del componente

A continuación, el lado de COM mantiene en el manifiesto del componente la información que originalmente residía en el registro.

Aquí se incluye, por ejemplo, información como esta:

  • comClass
  • clsid
  • progid
  • threadingModel
  • typelib
  • si hace falta, proxy / stub, clases de ventana, etc.

En otras palabras, la idea es describir en XML el «aspecto» de COM, en lugar de guardarlo en el registro.

Este manifiesto se puede configurar de dos formas:

  • Colocarlo en un archivo separado de la DLL
  • Incrustarlo como recurso dentro de la DLL

En la práctica, incrustarlo en la DLL como private assembly suele generar menos incidentes. Manejarlo como archivo separado es fácil de entender, pero es más propenso a tropiezos por la correspondencia entre el nombre de archivo y el assemblyIdentity, la ubicación de los archivos y las copias olvidadas.

5.3 En tiempo de ejecución se consulta primero el contexto de activación

Aquí está el núcleo de Reg-Free COM.

Cuando la aplicación llama a CLSIDFromProgID o CoCreateInstance, el runtime de COM consulta el contexto de activación activo. Si allí está la información necesaria de ProgID → CLSID y CLSID → DLL, puede resolverse sin usar el registro.

Por el contrario, si falta información necesaria en el manifiesto, se recurre a la resolución tradicional basada en registro. Este comportamiento provoca una trampa: funciona por casualidad en la máquina de desarrollo. Se cree que la configuración quedó como Reg-Free, cuando en realidad se está apoyando en un registro local.

Esta es la trampa más traicionera de Reg-Free COM.

6. Qué ventajas ofrece

Las ventajas de Reg-Free COM son bastante claras en la práctica.

6.1 Facilita la distribución por copia directa (XCOPY)

Como se pueden reunir todos los archivos necesarios en la carpeta de la aplicación, el instalador y el proceso de registro se vuelven más ligeros. Por supuesto, escribir dentro de Program Files es otra cuestión en materia de permisos, pero al menos suele ser posible reducir el trabajo administrativo necesario para el registro de COM.

6.2 Reduce los conflictos de versión

Aunque en la misma máquina haya varias versiones de un componente COM, resulta más fácil separar la versión que usa cada aplicación. Esto ayuda bastante a evitar el incidente de «el comportamiento cambió de repente por la instalación de otro producto».

6.3 En muchos casos no hace falta modificar demasiado el código existente

Reg-Free COM es un mecanismo que cambia la forma de resolución, más que obligar a rehacer desde la raíz la forma en que se llama al código existente. Por eso, cuando encaja bien, se puede introducir tocando muy poco el código del lado de CoCreateInstance.

6.4 Facilita la eliminación y la reversión

Al quedar todo contenido dentro del ámbito de la aplicación, las actualizaciones y las reversiones se vuelven bastante más sencillas. Llevado al extremo, se vuelve viable la idea de reemplazar toda la carpeta.

7. Escenarios adecuados y no adecuados

7.1 Escenarios adecuados

En casos como estos, Reg-Free COM es bastante recomendable:

Situación Compatibilidad
Se quiere incluir una COM DLL / OCX exclusiva de la aplicación Muy buena
Se quiere que convivan varias versiones en el mismo PC Muy buena
Se quiere evitar incidentes de registro provocados por componentes de proveedores Buena
Se quiere usar ActiveX / OCX de forma privada en una aplicación de escritorio existente Buena
Se quiere aligerar la distribución sin cambiar mucho las llamadas existentes Buena

Típicamente, encaja bien con aplicaciones de escritorio de negocio, herramientas de integración con equipos y activos existentes en VB6 / MFC / WinForms.

7.2 Escenarios no adecuados, o que requieren cautela

Por otro lado, hay casos en los que conviene ser cauteloso:

Situación Comentario
Se quiere compartir COM en toda la máquina El beneficio de Reg-Free se diluye
La bitness no coincide Reg-Free no lo resuelve
Hay una fuerte dependencia de información de registro no estándar o de instaladores propios Es difícil convertirlo en manifiesto
No está resuelta la distribución de las DLL dependientes o del runtime de VC++ Al final el fallo aparece en otro lugar
Las herramientas de diseño o la configuración de referencias del IDE dan por hecho el registro Se necesita un diseño operativo distinto

Este último punto en particular es importante. Reg-Free COM ayuda con la activación en tiempo de ejecución, pero no cambia de un plumazo lo que da por supuesto la interfaz de configuración de referencias en tiempo de diseño.

8. Malentendidos habituales

8.1 «Con Reg-Free COM desaparece el problema de bitness»

No desaparece. Un proceso de 32 bits solo puede cargar una COM DLL in-proc de 32 bits, y un proceso de 64 bits solo puede cargar una DLL de 64 bits. En esto, Reg-Free se comporta igual que siempre.

8.2 «Con Reg-Free COM nunca se consulta el registro»

Esto también es incorrecto. Si falta información necesaria en el manifiesto, se recurre a la resolución tradicional basada en registro. Por eso, que funcione en la máquina de desarrollo no significa necesariamente que la configuración Reg-Free sea correcta.

8.3 «Con Reg-Free COM el tema de la biblioteca de tipos también se resuelve automáticamente»

Esto solo es cierto en parte. En el manifiesto también se puede escribir información de typelib, pero es normal que el manejo de la información de tipos —como la configuración de referencias en VBA, el #import de C++ o la generación de referencias en tiempo de diseño en .NET— requiera un diseño aparte.

Reg-Free COM trata, ante todo, de conseguir que la aplicación se inicie. Cómo desarrollar de forma tipada es el siguiente punto a resolver.

8.4 «Con Reg-Free COM cualquier ActiveX / OCX funciona tal cual»

Esto también es peligroso. Si el componente sigue la información de registro COM estándar, es fácil avanzar, pero si depende mucho de configuraciones de registro propias, instaladores adicionales, procesamiento de licencias o un grupo aparte de módulos, la conversión a Reg-Free se complica de golpe.

8.5 «Reg-Free COM es más o menos lo mismo en .NET Framework y en .NET 8»

Hay puntos parecidos, pero la cadena de herramientas es bastante distinta. El contexto de .NET Framework + RegAsm y el de .NET 5+ / .NET 8 + comhost son, aunque ambos son COM, terrenos diferentes.

9. Diferencias entre nativo, .NET Framework, .NET 5+ y .NET 8

Este punto tiende a mezclarse, así que conviene separarlo aquí.

Familia Resumen general
COM DLL / OCX nativas La base es pensarlo en términos de manifiesto de la aplicación + manifiesto del componente
Interoperabilidad COM basada en .NET Framework Además del manifiesto de la aplicación al estilo Win32, también hace falta el manifiesto del lado del componente administrado
Exposición COM en .NET 5+ / .NET 8 Con EnableComHosting se crea el COM host, y con EnableRegFreeCom se puede generar el manifiesto para Reg-Free COM

9.1 COM basado en .NET Framework

En COM basado en .NET Framework se necesitan dos capas: el manifiesto de la aplicación al estilo Win32 del lado de la aplicación COM y el manifiesto del componente del lado del componente administrado.

Es decir, respecto a COM nativo, hay un manifiesto más. Las restricciones de nombre e ID de recurso del punto 10.4 se aplican de la misma manera a este manifiesto del componente.

9.2 Exposición de COM en .NET 5+ / .NET 8

En .NET 5+ / .NET 8, el punto de entrada para la exposición COM es *.comhost.dll. Además, si se activa EnableRegFreeCom=true, se genera el manifiesto side-by-side para Reg-Free COM.

Como se explica en 8.3, el manejo de la información de tipos queda como una cuestión aparte, pero en .NET Core / .NET 5+ esto cambia todavía más. Ya no es, como en la época de .NET Framework, un mundo en el que el TLB surge de forma natural a partir del ensamblado, así que si se necesita un uso tipado, hace falta organizar por separado la generación, incrustación y registro del TLB. Los pasos concretos están recogidos en «Cómo usar una DLL de .NET 8 desde VBA de forma tipada - Exposición COM y TLB con dscom».

10. Ejemplo de configuración mínima

Aquí mostramos un ejemplo mínimo en el que MyApp.exe usa Vendor.CameraControl.dll mediante Reg-Free COM.

10.1 Estructura de archivos de ejemplo

MyApp.exe
MyApp.exe.manifest
Vendor.CameraControl.Asm.manifest
Vendor.CameraControl.dll
Vendor.Helper.dll

En el ejemplo anterior se asume que el manifiesto del componente se coloca en un archivo separado. También es posible incrustarlo en la DLL, pero en ese caso el nombre del assembly y el ID de recurso quedan sujetos a restricciones concretas. Este procedimiento se trata paso a paso en 10.4.

10.2 Ejemplo de manifiesto de la aplicación

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity
    type="win32"
    name="KomuraSoft.MyApp"
    version="1.0.0.0"
    processorArchitecture="amd64" />

  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Vendor.CameraControl.Asm"
        version="1.0.0.0"
        processorArchitecture="amd64" />
    </dependentAssembly>
  </dependency>
</assembly>

10.3 Ejemplo de manifiesto del componente

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity
    type="win32"
    name="Vendor.CameraControl.Asm"
    version="1.0.0.0"
    processorArchitecture="amd64" />

  <file name="Vendor.CameraControl.dll">
    <comClass
      clsid="{01234567-89AB-CDEF-0123-456789ABCDEF}"
      progid="Vendor.CameraControl.1"
      threadingModel="Apartment"
      tlbid="{89ABCDEF-0123-4567-89AB-CDEF01234567}" />

    <typelib
      tlbid="{89ABCDEF-0123-4567-89AB-CDEF01234567}"
      version="1.0"
      helpdir="" />
  </file>
</assembly>

En este ejemplo, lo verdaderamente importante no son los detalles del XML, sino que el dependentAssembly del lado de la aplicación coincida con el assemblyIdentity del lado del componente. Si esto se desajusta, se produce un fallo de inicio cuya causa no se puede deducir solo con el aspecto del error.

Tenga en cuenta que el GUID y los nombres anteriores son solo ejemplos explicativos. En la práctica, hay que escribirlos correctamente conforme al CLSID / TLBID / ProgID / modelo de subprocesos que expone realmente el componente.

10.4 Dónde colocar el manifiesto y cómo incrustarlo

Este es el punto donde más se tropieza en el procedimiento. Según se coloque en un archivo separado o se incruste en el binario, cambia el nombre que se puede usar.

Side-by-side busca los private assembly en la carpeta de la aplicación siguiendo este orden:

  1. La carpeta WinSxS
  2. <appdir>\<assemblyname>.DLL
  3. <appdir>\<assemblyname>.manifest
  4. <appdir>\<assemblyname>\<assemblyname>.DLL
  5. <appdir>\<assemblyname>\<assemblyname>.manifest

Si se encuentra antes una DLL con el mismo nombre que el assembly, la búsqueda se detiene ahí. A partir de esto, solo son válidas estas dos combinaciones.

Forma de colocarlo Nombre del assembly Archivo ID de recurso de incrustación
Archivo separado Debe ser distinto del nombre de la DLL. Ejemplo: Vendor.CameraControl.Asm Vendor.CameraControl.Asm.manifest colocado junto a la DLL No se incrusta
Incrustado en la DLL Puede ser igual que el de la DLL. Ejemplo: Vendor.CameraControl Solo Vendor.CameraControl.dll 1

Es decir, si se usa el nombre Vendor.CameraControl.Asm como en los ejemplos de 10.2 y 10.3, esa es la convención del archivo separado. Para pasar a incrustación, hay que cambiar el name de assemblyIdentity a Vendor.CameraControl y alinear también el lado de dependentAssembly con el mismo nombre.

Hay otra restricción con la que es fácil equivocarse. El manifiesto del componente no se puede incluir como recurso del EXE. Lo que puede incluirse en el EXE es el manifiesto de la aplicación.

Para incrustarlo se usa mt.exe (la herramienta de manifiestos) del Windows SDK. Ejecútela desde el símbolo del sistema para desarrolladores de Visual Studio.

rem 1. Antes de incrustar, primero se valida la sintaxis
mt.exe -manifest MyApp.exe.manifest -validate_manifest
mt.exe -manifest Vendor.CameraControl.manifest -validate_manifest

rem 2. Incrustar el manifiesto de la aplicación en el EXE
mt.exe -manifest MyApp.exe.manifest -outputresource:MyApp.exe;#1

rem 3. Incrustar el manifiesto del componente en la DLL (el ID de recurso es 1)
mt.exe -manifest Vendor.CameraControl.manifest -outputresource:Vendor.CameraControl.dll;#1

rem 4. Extraerlo para comprobar que quedó incrustado
mt.exe -inputresource:Vendor.CameraControl.dll;#1 -out:extracted.manifest

Si compara el extracted.manifest obtenido con el cuarto comando frente al XML original, puede descartar el error de «creía haberlo incrustado, pero no estaba».

mt.exe tiene dos puntos de cuidado:

  • Los archivos referenciados por el manifiesto deben estar en el mismo directorio que el manifiesto. Si escribió <file name="Vendor.CameraControl.dll">, coloque esa DLL junto al manifiesto antes de ejecutar el comando. Si la salida de compilación y la ubicación del manifiesto están separadas, el proceso se detiene aquí
  • Si se omite el ID de recurso en -outputresource, se usa CREATEPROCESS_MANIFEST_RESOURCE (= 1). Para evitar que se convierta en 1 sin que sea intencional, es más legible dejar ;#1 de forma explícita

Si solo quiere reemplazar algo que ya está incrustado, puede usar -updateresource:<archivo>;#1. Esto equivale a pasar el mismo argumento tanto a -inputresource como a -outputresource.

10.5 Procedimiento de verificación, incluido un entorno limpio

Con Reg-Free COM, «funcionó en la máquina de desarrollo» prácticamente no significa nada, porque siempre queda la posibilidad de que solo se esté beneficiando de un registro local. Verifíquelo en este orden:

  1. Compile y reúna todo el paquete de distribución en una sola carpeta. Incluya el EXE, el manifiesto, la COM DLL, las DLL dependientes, el runtime de VC++ y las DLL de proxy / stub
  2. Prepare un entorno de verificación. Lo ideal es un entorno donde el COM en cuestión no se haya registrado nunca. Con Windows Sandbox puede probarlo cada vez desde un estado completamente limpio
  3. En ese entorno, confirme primero que el COM en cuestión no está registrado. Si el comando siguiente devuelve un error indicando que no se encuentra la clave, es que no está registrado
  4. Copie la carpeta e inícielo tal cual. No ejecute el instalador ni regsvr32
  5. Confirme que la creación del objeto COM se completa correctamente. El mero inicio no verifica los componentes de creación diferida. Ejecute realmente la pantalla o la función en la que se llama a CoCreateInstance
  6. Si falla, tome los registros siguiendo el procedimiento de 11.2

El comando que se usa en el paso 3 es este:

reg query "HKCR\CLSID\{01234567-89AB-CDEF-0123-456789ABCDEF}" /reg:64
reg query "HKCR\CLSID\{01234567-89AB-CDEF-0123-456789ABCDEF}" /reg:32
reg query "HKCR\Vendor.CameraControl.1"

Las vistas de registro de 32 bits y de 64 bits son independientes, así que revise siempre la que corresponda a la bitness de la aplicación. Es más seguro comprobar tanto /reg:64 como /reg:32.

Si quiere probarlo en la máquina de desarrollo, primero quite el registro con regsvr32 /u Vendor.CameraControl.dll y verifique después. Sin embargo, en un entorno donde otro producto use el mismo COM esto puede afectarlo, así que es más seguro preparar un entorno limpio.

11. Problemas frecuentes

11.1 Funciona en la máquina de desarrollo pero no en el destino de distribución

Lo primero que hay que sospechar es que en realidad se estaba beneficiando de un registro en el registro de Windows. Es más seguro verificar Reg-Free COM, en la medida de lo posible, en un entorno limpio.

11.2 No se inicia con el error «side-by-side configuration is incorrect»

Este tipo de error se produce por inconsistencias en el manifiesto, falta de DLL dependientes, falta del runtime de VC++, diferencias de arquitectura, etc. El texto del error por sí solo suele ser bastante poco informativo, así que lo habitual es investigarlo con el registro de eventos y con sxstrace.

Para el registro de eventos, abra el Visor de eventos > Registros de Windows > Aplicación, y busque los errores cuyo origen sea SideBySide. Ahí aparece en la resolución de qué assembly falló.

sxstrace se toma reproduciendo el fallo. Es más seguro abrir el símbolo del sistema como administrador.

rem 1. Iniciar la traza. Deje esta ventana abierta
sxstrace trace -logfile:sxstrace.etl

rem 2. En otra ventana, inicie la aplicación y reproduzca el fallo

rem 3. Detener la traza. Pulse Entrar en la ventana del paso 1, o ejecute lo siguiente desde otra ventana
sxstrace stoptrace

rem 4. Convertir el .etl sin procesar a un formato legible
sxstrace parse -logfile:sxstrace.etl -outfile:sxstrace.txt

Si no quiere que aparezca el mensaje para detener, añada -nostop en el paso 1. Si la salida es demasiado larga, añadir -filter:MyApp.exe en el paso 4 permite acotarla solo a la aplicación en cuestión.

En el sxstrace.txt resultante aparecen, en orden, qué manifiesto se buscó y en qué punto no hubo coincidencia. Incluso si se equivocó en la convención de nombres de 10.4, aquí puede verlo mirando «el nombre de archivo que se fue a buscar».

11.3 Desajuste entre el manifiesto del componente y el de la aplicación

  • El name es distinto
  • La version es distinta
  • El processorArchitecture es distinto
  • El manifiesto que creía haber copiado en realidad está desactualizado

Estas diferencias parecen mínimas a simple vista, pero tienen un efecto bastante grande en el inicio.

11.4 Olvidar colocar las DLL dependientes

Si se conforma con revisar solo Vendor.CameraControl.dll, se olvida de Vendor.Helper.dll, del runtime de VC++ y de las DLL de proxy / stub que se leen más adelante. Reg-Free COM reduce los problemas de registro de COM, pero no hace desaparecer los problemas de resolución de dependencias nativas.

11.5 Postergar la gestión de la biblioteca de tipos y las referencias

Aunque solo se resuelva la activación en tiempo de ejecución, si se necesita:

  • Enlace temprano (early binding) desde VBA
  • #import en C++
  • Generar interop en tiempo de diseño en .NET

entonces hace falta una forma de distribuir la información de tipos. Reg-Free COM no organiza todo esto de forma automática, así que es importante separar el pensamiento entre tiempo de ejecución (runtime) y tiempo de diseño (design-time).

12. Resumen

Si tuviera que resumir Reg-Free COM en una frase, sería: un mecanismo que traslada la información de registro de COM del ámbito de toda la máquina al ámbito de cada aplicación.

Esto aporta las siguientes ventajas:

  • Facilita mantener la COM DLL / OCX aislada por aplicación
  • Facilita reducir los conflictos de versión
  • Facilita simplificar la distribución y la reversión

Por otro lado, siguen siendo importantes:

  • 32 bits / 64 bits
  • Las DLL dependientes
  • El TLB / la configuración de referencias
  • Las dependencias de registro no estándar
  • La verificación en un entorno limpio

Por eso, la actitud básica al introducir Reg-Free COM es esta:

  1. Asumir que esto es una cuestión de activación
  2. Separar los puntos de runtime y de design-time
  3. Verificarlo en un entorno limpio
  4. Alinear primero la bitness y las DLL dependientes

Si lo aborda en este orden, el riesgo de incidentes se reduce bastante.

13. Artículos relacionados

14. Referencias

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.

¿Qué es Reg-Free COM?
Es un mecanismo que mantiene la información de registro de COM en un manifiesto en lugar de en el registro de Windows; su nombre es la abreviatura de Registration-Free COM. En tiempo de ejecución, al resolver CoCreateInstance o CLSIDFromProgID, primero se consulta el contexto de activación, y a partir de la información del manifiesto escrita allí se resuelve la DLL correspondiente. Esto permite mantener la COM DLL / OCX de forma privada por aplicación, con ventajas como facilitar la distribución por copia directa (XCOPY), evitar más fácilmente los conflictos de versión y reducir el riesgo de que una desinstalación quede rota.
¿Con Reg-Free COM también se resuelve el problema de 32 bits / 64 bits?
No se resuelve. Un proceso de 32 bits solo puede cargar una COM DLL in-proc de 32 bits, y un proceso de 64 bits solo puede cargar una DLL de 64 bits. En esto, Reg-Free se comporta igual que siempre. Además, hay que seguir considerando por separado la distribución de las DLL dependientes y del runtime de VC++, las bibliotecas de tipos, la configuración de referencias en tiempo de diseño y la dependencia de información de registro no estándar. Lo que Reg-Free COM elimina es, sobre todo, la molestia derivada del registro global.
¿Por qué una configuración de Reg-Free COM funciona en la máquina de desarrollo pero no en el destino de distribución?
Lo primero que hay que sospechar es que, en realidad, se estaba beneficiando de un registro previo en el registro de Windows. Cuando falta información necesaria en el manifiesto, el runtime de COM recurre a la resolución tradicional basada en registro, por lo que en la máquina de desarrollo puede funcionar por casualidad gracias a un registro local. Por eso es más seguro verificar Reg-Free COM en un entorno limpio. Si la aplicación no se inicia con el error «side-by-side configuration is incorrect», suele deberse a inconsistencias en el manifiesto o a la falta de DLL dependientes, y lo habitual es investigarlo con el registro de eventos y sxstrace.
¿También se puede convertir en Reg-Free COM un componente COM creado con .NET 8?
Sí, es posible. En .NET 5+/.NET 8, con EnableComHosting se genera el archivo *.comhost.dll que actúa como punto de entrada para la exposición COM, y si además se activa EnableRegFreeCom=true, se genera el manifiesto side-by-side para Reg-Free COM. Sin embargo, Reg-Free COM y la estrategia de TLB son cuestiones distintas. En .NET Core/.NET 5+ el TLB ya no se genera de forma natural a partir del ensamblado como ocurría en la época de .NET Framework, así que si se necesita un uso tipado, como el enlace temprano (early binding) desde VBA, es más seguro organizar por separado la generación, incrustación y registro del TLB.

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