Cómo usar una DLL de .NET 8 desde VBA con tipado - Exposición COM y TLB con dscom

· Actualizado el: · · C#, .NET 8, VBA, COM, Office, dscom

Todavía es habitual querer invocar procesamiento de .NET 8 desde VBA. En particular, cuando se desea conservar tal cual los activos existentes de Excel o Access, pero delegar en C# únicamente las partes pesadas: procesamiento de cadenas, HTTP, cifrado o lógica de negocio.

Sin embargo, si se recurre al enlace tardío con CreateObject, el lado de VBA termina lleno de Object. IntelliSense pierde fuerza, los errores de tipeo en los nombres de métodos no se detectan hasta la ejecución, y poco a poco se va hundiendo en un terreno cada vez más dependiente de cadenas de texto.

Por eso, en este artículo nos centramos en exponer una DLL de .NET 8 como COM, generar la biblioteca de tipos (TLB) con dscom y usarla desde VBA con tipado mediante enlace temprano.

Dejamos de lado, por ahora, la vieja historia de .NET Framework + RegAsm, la de escribir IDL a mano y compilarlo con MIDL, y la de Reg-Free COM. Aquí tratamos solo el camino directo de .NET 8 / COM host / dscom / enlace temprano en VBA.

El código que aparece en este artículo está publicado en GitHub como un conjunto completo de ejemplos que puede compilar y verificar (biblioteca expuesta a COM, scripts de generación y registro del TLB, módulos de VBA y pruebas unitarias).

dotnet8-dll-typed-vba-com-dscom-tlb - komurasoft-blog-samples (GitHub)

Entorno necesario

Elemento Qué se necesita
SO Windows. Como se realiza el registro COM, debe poder ejecutar regsvr32 con permisos de administrador
SDK de .NET SDK de .NET 8. EnableComHosting es una función disponible desde .NET 5 en adelante
Office Excel o Access. Compruebe primero si es la versión de 32 o 64 bits (capítulo 3)
Herramienta de generación del TLB dscom. El método de obtención difiere entre la versión de 64 bits y la de 32 bits (capítulo 6)
PC cliente Runtime de .NET 8 con la misma bitness que Office (capítulo 9)

Antes de entrar en el procedimiento, se recomienda encarecidamente anotar las versiones de su propio entorno. Si más adelante ocurre que «siguió los mismos pasos pero no funciona», esta es la única información que le permitirá comparar.

# Lista de SDK y runtimes de .NET (también indica si tiene instalado x64 o x86)
dotnet --info

# Número de compilación (build) de Windows
winver

La versión y la bitness de Office se pueden comprobar en Excel desde Archivo > Cuenta > Acerca de Excel. Al final de la línea de título del cuadro de diálogo aparece 32 bits o 64 bits.

1. Conclusión por adelantado

Si adelantamos solo la conclusión, el flujo es el siguiente.

  • Compile la biblioteca de clases de .NET 8 con EnableComHosting=true
  • Cree una interfaz y una clase explícitas que se expongan a COM
  • Deje la clase como ClassInterfaceType.None, sin recurrir a AutoDual
  • Marque como InterfaceIsDual la interfaz que usará VBA
  • A partir del *.dll generado tras la compilación, cree el *.tlb con dscom tlbexport
  • Registre *.comhost.dll con regsvr32
  • Registre *.tlb con dscom tlbregister
  • Agregue la referencia en VBA y úselo con tipado, como en Dim x As NombreDeLaLibrería.IYourInterface

En resumen, la arquitectura es esta: la puerta de entrada COM es el *.comhost.dll que genera el SDK de .NET, la información de tipos es el *.tlb que genera dscom, y VBA consulta ese TLB para hacer enlace temprano.

2. Panorama general de esta arquitectura

Primero, veamos en un solo diagrama qué papel cumple cada pieza.

Panorama general de la arquitectura de este artículoVBA obtiene información de tipos del TLB agregado en las referencias y realiza llamadas COM al COM host, que a su vez invoca la DLL de .NET 8, la cual se ejecuta sobre el runtime de .NET 8Obtiene información de tipo del TLB agregado en ReferenciasLlamada COMVBA / Excel / AccessVbaTypedComSample.tlbVbaTypedComSample.comhost.dllVbaTypedComSample.dll (.NET 8).NET 8 Runtime

El papel de cada archivo es el siguiente.

Archivo Papel
VbaTypedComSample.dll Cuerpo de la implementación en .NET 8
VbaTypedComSample.comhost.dll Puerta de entrada invocada desde COM
VbaTypedComSample.tlb Información de tipos que consulta VBA
VbaTypedComSample.deps.json Información de resolución de dependencias
VbaTypedComSample.runtimeconfig.json Información de arranque del runtime de .NET

Lo importante aquí es que lo que VBA necesita para conocer los tipos es el TLB, y lo que se necesita como puerta de entrada de arranque COM es el comhost.

El hecho de que no baste con entregar solo el .dll es una de las particularidades poco intuitivas del mundo COM.

3. Lo primero que hay que decidir: hacer coincidir 32 bits y 64 bits

Si se pasa por alto este punto, es bastante probable que termine viendo el mensaje El componente ActiveX no puede crear el objeto.

Haga coincidir la bitness de Office/VBA con la del servidor COM.

Lado que usa Referencia del lado de .NET Generación del TLB Comando de registro
Office de 64 bits x64 / win-x64 dscom C:\Windows\System32\regsvr32.exe
Office de 32 bits (en Windows de 64 bits) x86 / win-x86 dscom32.exe C:\Windows\SysWOW64\regsvr32.exe

En el COM host de .NET 5+ en adelante, si se deja AnyCPU tal cual, el *.comhost.dll tiende a generarse del lado de 64 bits, y puede no coincidir con Office de 32 bits. Por eso es más seguro especificar explícitamente x86 / x64 según la versión de Office.

El código de este artículo toma como ejemplo Office de 64 bits. Si usa Office de 32 bits, sustituya más adelante x64 por x86 y win-x64 por win-x86.

4. Construcción del lado de .NET 8

Aquí construiremos un ejemplo mínimo en el que se puedan invocar Add, Divide y Hello desde VBA.

4.1 El archivo .csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <EnableComHosting>true</EnableComHosting>
    <PlatformTarget>x64</PlatformTarget>
    <NETCoreSdkRuntimeIdentifier>win-x64</NETCoreSdkRuntimeIdentifier>
  </PropertyGroup>
</Project>

El punto clave es EnableComHosting. Al añadirlo, durante la compilación se genera VbaTypedComSample.comhost.dll.

4.2 Dejar todo el ensamblado no visible para COM por defecto

Como solo queremos que los tipos que se van a exponer a COM tengan ComVisible(true), es más cómodo dejar todo el ensamblado en false.

using System.Runtime.InteropServices;

[assembly: ComVisible(false)]

4.3 Escribir la interfaz y la clase que se expondrán

using System.Runtime.InteropServices;

namespace VbaTypedComSample;

[ComVisible(true)]
[Guid("2A1BBEDE-DE6E-4C34-AD60-2E9E0E33E999")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ICalculator
{
    [DispId(1)]
    int Add(int x, int y);

    [DispId(2)]
    double Divide(double x, double y);

    [DispId(3)]
    string Hello(string name);
}

[ComVisible(true)]
[Guid("FAD1C752-0BB6-4DDD-889F-FE446350847A")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(ICalculator))]
public class Calculator : ICalculator
{
    public Calculator()
    {
    }

    public int Add(int x, int y) => checked(x + y);

    public double Divide(double x, double y)
    {
        if (y == 0)
        {
            throw new ArgumentOutOfRangeException(nameof(y), "No se puede dividir por 0.");
        }

        return x / y;
    }

    public string Hello(string name)
    {
        if (string.IsNullOrWhiteSpace(name))
        {
            return "Hello";
        }

        return $"Hello, {name}";
    }
}

Los puntos que conviene tener en cuenta de este código son los siguientes.

  • Asigne Guid por separado a la interfaz y a la clase
  • Use ClassInterfaceType.None para no depender de la interfaz de clase generada automáticamente
  • Marque como InterfaceIsDual para que sea fácil de manejar desde VBA
  • Asignar DispId ayuda a reducir problemas si más adelante se modifica el orden de los métodos ya publicados
  • Como COM la instancia con New, prepare un constructor público sin argumentos

5. Compilación

Compile en modo Release.

dotnet build -c Release

Tras la compilación, en la carpeta de salida aparecerán al menos los siguientes archivos.

bin/
  Release/
    net8.0-windows/
      VbaTypedComSample.dll
      VbaTypedComSample.comhost.dll
      VbaTypedComSample.deps.json
      VbaTypedComSample.runtimeconfig.json

Esta es la carpeta que se usa para la distribución y el registro. Si más adelante cambia la ubicación, tendrá que volver a registrar todo.

6. Generar el TLB con dscom

6.1 Qué es dscom

dscom es una herramienta de línea de comandos de código abierto para generar y registrar bibliotecas de tipos (TLB) de COM a partir de ensamblados de .NET. La publica la empresa dSPACE, bajo licencia Apache-2.0.

¿Por qué es necesaria? Porque desde .NET 5 en adelante se eliminaron tlbexp.exe y RegAsm.exe. En la época de .NET Framework, estas dos herramientas permitían generar el TLB y registrar el ensamblado, pero .NET 5+ no incluye de forma estándar un sucesor para ellas. dscom es la herramienta creada para llenar ese vacío.

Basta con recordar estos subcomandos principales.

Subcomando Función
tlbexport Exporta el TLB a partir del ensamblado
tlbregister Registra el TLB en el sistema
tlbunregister Anula el registro del TLB
tlbdump Vuelca el contenido del TLB para verificarlo
tlbembed Incrusta el TLB en un archivo

tlbdump resulta útil para comprobar, antes de abrir VBA, si el TLB generado contiene los tipos previstos.

6.2 Caso de 64 bits

Si solo necesita crear el TLB de 64 bits, puede instalarlo mediante dotnet tool.

dotnet tool install --global dscom

A continuación, genere el TLB a partir del ensamblado compilado.

dscom tlbexport .\bin\Release\net8.0-windows\VbaTypedComSample.dll --out .\bin\Release\net8.0-windows\VbaTypedComSample.tlb

6.3 Caso de Office de 32 bits: de dónde obtener dscom32.exe

Este es el punto donde más se suele atascar al dar soporte a Office de 32 bits.

El dscom que se instala con dotnet tool install solo puede manejar ensamblados AnyCPU o de 64 bits, y únicamente puede generar TLB de 64 bits. Para crear un TLB de 32 bits hace falta un ejecutable distinto, dscom32.exe, que no se obtiene de NuGet, sino que se descarga desde la página de lanzamientos (releases) de GitHub.

  • Fuente de descarga: https://github.com/dspace-group/dscom/releases
  • dscom.exe: crea un TLB de 64 bits a partir de un ensamblado AnyCPU o de 64 bits
  • dscom32.exe: crea un TLB de 32 bits a partir de un ensamblado AnyCPU o de 32 bits

En el ejemplo de este artículo, el dscom32.exe descargado se coloca en la carpeta tools justo debajo del proyecto. La ubicación es libre, pero no lo distribuya junto con la salida de la compilación. Es una herramienta de desarrollo, no algo necesario en tiempo de ejecución.

Hay otro requisito previo que se pasa por alto con facilidad: para ejecutar dscom32.exe es necesario tener instalado el runtime de .NET en la versión x86. Esto se debe a que dscom carga hostfxr.dll, y no funciona en entornos donde solo está instalada la versión x64. Compruebe en la lista que aparece en la salida de dotnet --info si tiene instalado el runtime x86.

.\tools\dscom32.exe tlbexport .\bin\Release\net8.0-windows\VbaTypedComSample.dll --out .\bin\Release\net8.0-windows\VbaTypedComSample.tlb

Además, la propia documentación de dscom recomienda que, puesto que dejar AnyCPU tal cual genera *.comhost.dll como de 64 bits, si se va a usar en 32 bits conviene compilar el propio ensamblado en 32 bits. Es la misma conclusión que la del capítulo 3.

Si resulta engorroso ejecutar el comando a mano en cada compilación, puede instalar el paquete dSPACE.Runtime.InteropServices.BuildTasks para generar el TLB automáticamente en el momento de compilar.

7. Registrar el COM host y el TLB

Ejecute esto desde un símbolo del sistema o PowerShell con permisos de administrador.

7.1 Caso de Office de 64 bits / COM de 64 bits

$out = Resolve-Path .\bin\Release\net8.0-windows

C:\Windows\System32\regsvr32.exe "$out\VbaTypedComSample.comhost.dll"
dscom tlbregister "$out\VbaTypedComSample.tlb"

7.2 Caso de Office de 32 bits (en Windows de 64 bits)

$out = Resolve-Path .\bin\Release\net8.0-windows

C:\Windows\SysWOW64\regsvr32.exe "$out\VbaTypedComSample.comhost.dll"
.\tools\dscom32.exe tlbregister "$out\VbaTypedComSample.tlb"

Aquí se están haciendo dos cosas.

  • Registrar *.comhost.dll como servidor COM con regsvr32
  • Registrar *.tlb como biblioteca de tipos con tlbregister

8. Agregar la referencia en VBA y usarlo con tipado

  1. Abra Excel o Access
  2. Abra el editor de VBA (VBE) con Alt + F11. Si prefiere abrirlo desde la cinta, es la pestaña Programador > Visual Basic. Si no aparece la pestaña Programador, actívela desde Archivo > Opciones > Personalizar cinta de opciones, marcando la casilla Programador
  3. En el menú del VBE, Herramientas > Referencias
  4. La lista de Bibliotecas disponibles aparece en orden alfabético. Si el registro se realizó correctamente, encontrará ahí el nombre de la biblioteca (por defecto, el mismo que el nombre del ensamblado, VbaTypedComSample); marque la casilla de la izquierda y pulse Aceptar
  5. Si no aparece en la lista, selecciónela directamente con el botón Examinar..., eligiendo VbaTypedComSample.tlb

Si no aparece en la lista, la causa suele ser una de estas dos: una discrepancia de bitness como la del capítulo 3, o que el tlbregister del capítulo 7 no se haya ejecutado correctamente. Desde Office de 32 bits no se ve un TLB registrado en 64 bits.

Para comprobar si la referencia se agregó correctamente, abra Ver > Examinador de objetos (F2) y verifique si puede seleccionar VbaTypedComSample en el selector de biblioteca de la esquina superior izquierda. Si aquí ve ICalculator y Calculator, así como Add / Divide / Hello, significa que el TLB se generó correctamente.

Option Explicit

Public Sub UseCalculator()
    Dim calc As VbaTypedComSample.ICalculator
    Set calc = New VbaTypedComSample.Calculator

    Debug.Print calc.Add(10, 20)
    Debug.Print calc.Divide(10, 4)
    Debug.Print calc.Hello("VBA")
End Sub

Coloque el cursor en este procedimiento, ejecútelo con F5 y abra la ventana Inmediato con Ctrl + G; verá tres líneas, tal como corresponde a la implementación del capítulo 4.

30
2.5
Hello, VBA

Si esto coincide con lo esperado, significa que todo funciona correctamente: la referencia, el registro COM, el arranque del runtime y el marshaling de argumentos y valores de retorno. Por el contrario, si los valores no coinciden, sospeche de la implementación del lado de .NET; y si directamente no se puede ejecutar, sospeche de los capítulos 3 y 7.

De este modo, del lado de VBA se obtienen estos beneficios.

  • IntelliSense funciona
  • Es más fácil detectar errores de tipeo en los nombres de métodos antes de ejecutar
  • Se puede comprobar la API expuesta en el Examinador de objetos
  • Es más legible que escribir todo con Object

8.1 Las excepciones se convierten en errores COM del lado de VBA

Por ejemplo, si se lanza una excepción del lado de .NET, como en Divide(10, 0), del lado de VBA se ve como un error COM.

Option Explicit

Public Sub UseCalculatorWithErrorHandling()
    On Error GoTo EH

    Dim calc As VbaTypedComSample.ICalculator
    Set calc = New VbaTypedComSample.Calculator

    Debug.Print calc.Divide(10, 0)
    Exit Sub

EH:
    Debug.Print Err.Number
    Debug.Print Hex$(Err.Number)
    Debug.Print Err.Description
End Sub

Conviene tener claro cómo interpretar los valores que aparecen aquí, para agilizar el diagnóstico.

Elemento Qué contiene
Err.Number Contiene el HRESULT correspondiente a la excepción de .NET, como un Long con signo. Como en decimal resulta difícil de leer, conviértalo a hexadecimal con Hex$(Err.Number)
Err.Description A través de IErrorInfo de COM, contiene tal cual el mensaje de la excepción de .NET. En el código anterior, es una cadena que incluye No se puede dividir por 0.

El valor del HRESULT está determinado por el tipo de excepción. El que corresponde a ArgumentOutOfRangeException es COR_E_ARGUMENTOUTOFRANGE, con el valor 0x80131502. Es decir, si Hex$(Err.Number) resulta en 80131502, significa que ha llegado, tal como se esperaba, el ArgumentOutOfRangeException del lado de .NET.

Los principales son los siguientes.

Excepción de .NET Constante HRESULT Valor
ArgumentException COR_E_ARGUMENT 0x80070057
ArgumentOutOfRangeException COR_E_ARGUMENTOUTOFRANGE 0x80131502
InvalidOperationException COR_E_INVALIDOPERATION 0x80131509
NotSupportedException COR_E_NOTSUPPORTED 0x80131515
Otras excepciones generales distintas de las anteriores COR_E_EXCEPTION 0x80131500

Si desea diferenciar el tratamiento según el tipo de excepción del lado de VBA, tendrá que ramificar según este HRESULT. Sin embargo, un diseño que ramifica según el HRESULT es frágil ante cambios en el tipo de excepción del lado de .NET, así que para los fallos de negocio resulta más estable devolver un valor de retorno o un código de error, en lugar de una excepción, como límite entre ambos mundos.

9. Consideraciones al distribuir

Lo importante al distribuir es colocar todo el conjunto de la salida, en lugar de repartir solo la DLL.

VbaTypedComSample.dll
VbaTypedComSample.comhost.dll
VbaTypedComSample.deps.json
VbaTypedComSample.runtimeconfig.json
VbaTypedComSample.tlb
(si es necesario, el conjunto de DLL de dependencias)

Además, el PC cliente necesita el runtime de .NET 8 correspondiente. El COM host no se distribuye como self-contained, sino que, básicamente, funciona en modo framework-dependent.

En concreto, esto es lo que hay que instalar.

  • La página de distribución es Descargas de .NET 8
  • Lo que se necesita no es el SDK, sino el runtime. Como el ejemplo de este artículo es una biblioteca de clases sin interfaz gráfica, basta con .NET Runtime. Si se usan tipos de WPF o Windows Forms, se necesita .NET Desktop Runtime
  • La bitness debe coincidir con la de Office. Si Office es de 64 bits, use el runtime x64; si es de 32 bits, use x86. Por el mismo motivo por el que en el capítulo 3 se especificó explícitamente x64 / x86, aquí también fallará el arranque si no coincide
  • Para saber si ya está instalado, ejecute dotnet --list-runtimes en el PC cliente y compruebe si aparece una línea con Microsoft.NETCore.App 8.x

Asegúrese de anotar en el material de distribución este «tipo, versión y bitness del runtime necesario». Si se olvida de incluirlo en el procedimiento de instalación, en el sitio del cliente acabarán viendo El componente ActiveX no puede crear el objeto., sospechando de la bitness y perdiendo tiempo.

10. Errores comunes (puntos donde se suele atascar)

10.1 No dejar AnyCPU sin cambiar

Si la bitness de VBA/Office y la del COM host no coinciden, se produce un tipo de fallo bastante desconcertante.

  • Si es Office de 64 bits: x64 / win-x64
  • Si es Office de 32 bits: x86 / win-x86

10.2 No usar ClassInterfaceType.AutoDual

A primera vista resulta cómodo, pero es fácil de romper si se modifica el orden o la composición de los miembros después de publicarlo.

Si quiere usarlo de forma estable y con tipado desde VBA, la práctica habitual es definir una interfaz explícita y dejar la clase como ClassInterfaceType.None.

10.3 No regenerar el GUID a la ligera

En COM, el GUID es en sí mismo el contrato. Si se sustituye el IID o el CLSID a la ligera después de publicarlo, se rompen las referencias y los registros existentes en VBA.

10.4 No romper interfaces ya publicadas

En COM, incluso algo tan aparentemente inofensivo como «añadir un solo método más tarde» puede no salir bien parado.

  • Conserve ICalculator
  • Si el cambio es grande, cree una nueva ICalculator2
  • La clase puede implementar ambas

10.5 Preferir tipos sencillos y discretos

En el límite que se expone a VBA, es más seguro no complicarse demasiado.

Para empezar, los tipos que funcionan bien son estos.

  • int
  • double
  • bool
  • string
  • DateTime
  • decimal
  • enum

10.6 No actualizar con Office abierto

Excel o Access pueden quedarse reteniendo la DLL, lo que puede causar problemas al compilar o volver a registrar.

  • Cierre Office
  • Anule el registro si es necesario
  • Vuelva a compilar
  • Registre de nuevo

La anulación del registro se realiza en el orden inverso al del registro, usando el comando de la misma bitness que se utilizó para registrar. También aquí se necesitan permisos de administrador, igual que al registrar.

# Caso de Office de 64 bits / COM de 64 bits
$out = Resolve-Path .\bin\Release\net8.0-windows

dscom tlbunregister "$out\VbaTypedComSample.tlb"
C:\Windows\System32\regsvr32.exe /u "$out\VbaTypedComSample.comhost.dll"
# Caso de Office de 32 bits (en Windows de 64 bits)
$out = Resolve-Path .\bin\Release\net8.0-windows

.\tools\dscom32.exe tlbunregister "$out\VbaTypedComSample.tlb"
C:\Windows\SysWOW64\regsvr32.exe /u "$out\VbaTypedComSample.comhost.dll"

La opción /u de regsvr32 es la de anulación de registro. Si usa un regsvr32 distinto del que usó para registrar, no podrá anularlo (lo que se registró en 64 bits no se puede quitar con el regsvr32 de SysWOW64). Si no anula el registro antes de mover o eliminar toda la carpeta, quedará en el registro una entrada que apunta a una ruta que ya no existe.

11. Resumen

El tema de «usar una DLL de .NET 8 con tipado desde VBA» no resulta un procedimiento tan intimidante si se centra en exponerla a COM y generar el TLB con dscom. Del lado de .NET 8, active EnableComHosting=true y prepare una interfaz explícita (la clase como ClassInterfaceType.None, y la orientada a VBA como InterfaceIsDual); cree el TLB con dscom tlbexport; registre *.comhost.dll con regsvr32 y *.tlb con dscom tlbregister. Después, solo queda agregar la referencia en VBA y usar el enlace temprano.

Cuando tenga dudas, el truco es pensar por separado en el COM host y en el TLB.

  • La puerta de entrada de arranque es *.comhost.dll
  • La información de tipos es *.tlb
  • El cuerpo de la implementación es *.dll

12. 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é se necesita para usar una DLL de .NET 8 desde VBA con tipado (enlace temprano)?
Compile la biblioteca de clases de .NET 8 con EnableComHosting=true para generar *.comhost.dll, y cree *.tlb con dscom tlbexport. A continuación registre *.comhost.dll con regsvr32 y *.tlb con dscom tlbregister; si añade ese TLB en las referencias de VBA, podrá usarlo con tipado de la forma Dim x As NombreDeLaLibrería.IYourInterface. En cuanto al reparto de roles: *.comhost.dll es la puerta de entrada COM, *.tlb es la información de tipos que ve VBA, y *.dll es el cuerpo de la implementación.
¿Cuál es la causa del mensaje «El componente ActiveX no puede crear el objeto»?
La causa típica es una discrepancia de bitness entre Office/VBA y el servidor COM. Si es Office de 64 bits, compile con x64/win-x64 y registre con el regsvr32 de System32; si es Office de 32 bits (sobre Windows de 64 bits), compile con x86/win-x86 y registre con el regsvr32 de SysWOW64, usando también dscom32.exe para generar el TLB. En el COM host de .NET 5 en adelante, si se deja AnyCPU tal cual, *.comhost.dll tiende a generarse del lado de 64 bits, lo que puede no coincidir con Office de 32 bits; por eso es más seguro especificar explícitamente x86/x64 según la versión de Office.
¿No se debe usar ClassInterfaceType.AutoDual?
A primera vista parece cómodo, pero debe evitarse porque es fácil de romper si se modifica el orden o la composición de los miembros después de publicarlo. Si quiere usarlo de forma estable y con tipado desde VBA, la práctica habitual es definir una interfaz explícita, dejar la clase como ClassInterfaceType.None y marcar la interfaz que usa VBA como InterfaceIsDual. Asignar DispId ayuda a reducir problemas cuando cambia el orden de los métodos. Además, en COM el GUID es en sí mismo el contrato, así que si se regenera el IID o el CLSID a la ligera después de publicarlo, se rompen las referencias y los registros existentes en VBA.
¿Basta con entregar solo la DLL al distribuir?
No, con la DLL sola no funciona. Debe colocar juntos el *.dll del cuerpo de la implementación, *.comhost.dll, *.deps.json, *.runtimeconfig.json, *.tlb y, si es necesario, el conjunto de DLL de dependencias. Además, el PC cliente necesita el runtime de .NET 8 correspondiente, ya que el COM host no se distribuye como self-contained sino que, básicamente, funciona en modo framework-dependent. Tenga en cuenta también que, si más adelante cambia la ubicación de los archivos, tendrá que volver a registrar todo.

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