Actualmente estoy tratando de crear un objeto COM en .NET Core 6. Para lograr esto, hice una biblioteca de clases y edité el proyecto de esta manera:
C#:
Archivo de proyecto (*.csproj):
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <EnableComHosting>true</EnableComHosting> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PlatformTarget>x86</PlatformTarget> </PropertyGroup> </Project>Objeto COM (*.cs):
using System; using System.Runtime.InteropServices; namespace COMNetCore6 { [ComVisible(true)] [Guid("64D6F9F6-6163-401A-82E6-C941CAF01399")] [ProgId("HelloWorldCOMObject")] public class ComObject { public string SayHello() => "Hello world from .NET Core"; } }Después de compilar el proyecto, obtengo un archivo *.comhost.dll que puedo agregar al registro usando el comando 'regsvr32 *.comhost.dll'. El comhost.dll se registra con éxito y funciona para Visual Basic en Excel según lo previsto .
Cuando intento usar este objeto COM en otro lenguaje de programación, no funcionará. He intentado usar Octave y Python. Si bien Octave solo me dice que no pudo crear un servidor, Python me da al menos este error:
Pitón:
>>> import win32com.client >>> comobj = win32com.client.Dispatch("HelloWorldCOMObject") Traceback (most recent call last): File "C:\*\AppData\Local\Programs\Python\Python39-32\lib\site-packages\win32com\client\dynamic.py", line 86, in _GetGoodDispatch IDispatch = pythoncom.connect(IDispatch) pywintypes.com_error: (-2147221021, 'Operation unavailable', None, None) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\*\AppData\Local\Programs\Python\Python39-32\lib\site-packages\win32com\client\__init__.py", line 117, in Dispatch dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch, userName, clsctx) File "C:\*\AppData\Local\Programs\Python\Python39-32\lib\site-packages\win32com\client\dynamic.py", line 106, in _GetGoodDispatchAndUserName return (_GetGoodDispatch(IDispatch, clsctx), userName) File "C:\*\AppData\Local\Programs\Python\Python39-32\lib\site-packages\win32com\client\dynamic.py", line 88, in _GetGoodDispatch IDispatch = pythoncom.CoCreateInstance( pywintypes.com_error: (-2147467262, 'No such interface supported', None, None)He intentado solucionar este problema siguiendo los pasos descritos en estos enlaces ( especialmente el primero ) y adaptándolos a lo que necesitaba:
¿Puedo conectar un objeto de interoperabilidad COM .NET 5 con VB6? https://github.com/GregReddick/ComTestLibrary/tree/master/ComTestLibrary1 https://docs.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com
Desafortunadamente, ninguno de los enfoques que probé funcionó. Intenté crear una interfaz para el objeto COM y usar las anotaciones de interoperabilidad correctas en C#, pero el error seguía ahí. Como he dicho, aunque el enfoque básico sin interfaz y apenas ninguna anotación de arriba funcionó para Visual Basic.
En este caso, estoy tratando de usar el enlace tardío sin TLB (biblioteca de tipos) porque necesito que esto funcione tanto para el enlace tardío (sin TLB) como para el enlace temprano (con TLB) y decidí comenzar con el enlace tardío.
Ha habido una pregunta similar con respecto al enfoque de enlace tardío que no se respondió a partir de ahora: "No se admite dicha interfaz" cuando se usa el objeto COM .NET 6.0 en python 3.9 .
Dado que el objeto COM funciona bien para Visual Basic pero no funciona para otros lenguajes de programación, no estoy seguro de qué causa exactamente este problema.
El contenedor de .NET Core no admite este tipo de llamada en la que solicita IDispatch al mismo tiempo que crea el objeto COM:
C/C++:
IDispatch* disp; CoCreateInstance(YourCLSID, NULL, CLSCTX_ALL, IID_IDispatch, &disp); // failsPitón:
disp = pythoncom.CoCreateInstance(YourCLSID, None, pythoncom.CLSCTX_ALL, pythoncom.IID_IDispatch) // failsPrimero debe obtener una referencia IUnknown y QI para IDispatch, como esta en python (que es lo que hace Excel/VBA):
import pythoncom import pywintypes from win32com.client import Dispatch unk = pythoncom.CoCreateInstance(pywintypes.IID('{64D6F9F6-6163-401A-82E6-C941CAF01399}'), None, pythoncom.CLSCTX_ALL, pythoncom.IID_IUnknown) disp = Dispatch(unk.QueryInterface(pythoncom.IID_IDispatch)) print disp.SayHelloEn mi humilde opinión, el soporte COM de python debe modificarse para hacer esto siempre ...