.NET Core 6.0 COM 与 Python/Octave 的互操作性问题
.NET Core 6.0 COM interoperability issues with Python/Octave
我目前正在尝试在 .NET Core 6 中创建一个 COM 对象。为此,我创建了一个 class 库并像这样编辑项目:
C#:
项目文件 (*.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>
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";
}
}
构建项目后,我得到一个 *.comhost.dll 文件,我可以使用命令 'regsvr32 *.comhost.dll' 将其添加到注册表中。 comhost.dll 注册成功 并且 它按预期在 Excel 中为 Visual Basic 工作。
当我尝试在另一种编程语言中使用此 COM 对象时,它不起作用。我试过使用 Octave 和 Python。虽然 Octave 只告诉我它无法创建服务器,但 Python 至少给我这个错误:
Python:
>>> 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)
我已尝试按照这些链接中描述的步骤(尤其是第一个)并根据我的需要调整它们来解决此问题:
https://github.com/GregReddick/ComTestLibrary/tree/master/ComTestLibrary1
https://docs.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com
不幸的是 none 我试过的方法奏效了。我试图为 COM 对象创建一个接口并在 C# 中使用正确的互操作性注释,但错误仍然存在。正如我所说的,没有界面且几乎没有任何来自上面的注释的基本方法适用于 Visual Basic。
在这种情况下,我尝试使用没有 TLB(类型库)的后期绑定,因为我需要它同时适用于后期绑定(没有 TLB)和早期绑定(有 TLB),我决定从后期开始绑定。
有一个关于延迟绑定方法的类似问题,目前还没有回答:'No such interface supported' when using .NET 6.0 COM object in python 3.9。
由于 COM 对象适用于 Visual Basic,但不适用于其他编程语言,我不确定究竟是什么导致了这个问题。
.NET Core 包装器不支持您在创建 COM 对象的同时请求 IDispatch 的此类调用:
C/C++:
IDispatch* disp;
CoCreateInstance(YourCLSID, NULL, CLSCTX_ALL, IID_IDispatch, &disp); // fails
Python:
disp = pythoncom.CoCreateInstance(YourCLSID, None, pythoncom.CLSCTX_ALL, pythoncom.IID_IDispatch) // fails
您必须首先获得 IUnknown 引用和 IDispatch 的 QI,就像 python 中的这样(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.SayHello
恕我直言,python 应该修改 COM 支持以始终执行此操作...
我目前正在尝试在 .NET Core 6 中创建一个 COM 对象。为此,我创建了一个 class 库并像这样编辑项目:
C#:
项目文件 (*.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>
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";
}
}
构建项目后,我得到一个 *.comhost.dll 文件,我可以使用命令 'regsvr32 *.comhost.dll' 将其添加到注册表中。 comhost.dll 注册成功 并且 它按预期在 Excel 中为 Visual Basic 工作。
当我尝试在另一种编程语言中使用此 COM 对象时,它不起作用。我试过使用 Octave 和 Python。虽然 Octave 只告诉我它无法创建服务器,但 Python 至少给我这个错误:
Python:
>>> 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)
我已尝试按照这些链接中描述的步骤(尤其是第一个)并根据我的需要调整它们来解决此问题:
不幸的是 none 我试过的方法奏效了。我试图为 COM 对象创建一个接口并在 C# 中使用正确的互操作性注释,但错误仍然存在。正如我所说的,没有界面且几乎没有任何来自上面的注释的基本方法适用于 Visual Basic。
在这种情况下,我尝试使用没有 TLB(类型库)的后期绑定,因为我需要它同时适用于后期绑定(没有 TLB)和早期绑定(有 TLB),我决定从后期开始绑定。
有一个关于延迟绑定方法的类似问题,目前还没有回答:'No such interface supported' when using .NET 6.0 COM object in python 3.9。
由于 COM 对象适用于 Visual Basic,但不适用于其他编程语言,我不确定究竟是什么导致了这个问题。
.NET Core 包装器不支持您在创建 COM 对象的同时请求 IDispatch 的此类调用:
C/C++:
IDispatch* disp;
CoCreateInstance(YourCLSID, NULL, CLSCTX_ALL, IID_IDispatch, &disp); // fails
Python:
disp = pythoncom.CoCreateInstance(YourCLSID, None, pythoncom.CLSCTX_ALL, pythoncom.IID_IDispatch) // fails
您必须首先获得 IUnknown 引用和 IDispatch 的 QI,就像 python 中的这样(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.SayHello
恕我直言,python 应该修改 COM 支持以始终执行此操作...